用Python爬取网络数据到Excel

1. 写在前面

1.1 说明

近来笔者在浅尝python网络爬虫,这是笔者写的第一个爬虫程序,仅仅是一步步按参考书的教程写成。写这篇博客仅为备忘用,没有什么技术含量,如果能对你有所帮助,那也再好不过。

我们以爬取酷狗歌曲TOP500为例,获取网页上显示的TOP500的歌曲名、歌手、歌曲时长,并将结果输出到一个Excel表格中。

1.2 环境与准备

  • Ubuntu 18.04

  • python 3.8

  • python库:Requests,BeautifulSoup4

  • chrome / firefox浏览器

  • 一双敲代码的小手

  • 一个不畏bug的大心脏

2. HTML爬取

第一步就是直接步入主题,用程序请求网站获取网页html文件。我们要做的事情就是:

  1. 加入请求头来伪装成浏览器

  2. 向目标网站发送http请求

  3. 获取服务器响应的html文件

应用“让HTTP服务人类”的Requests库,我们能够用一行代码实现这些操作。

1
2
3
4
5
import requests
headers = {
'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36"
}
wb_data = requests.get('https://www.kugou.com/yy/rank/home/1-8888.html',headers=headers)

其中,请求头可以从chrome浏览器的 开发者工具 > 网络 中查询。如此我们便获得了酷狗TOP500第一页的html文档,可以用print(wb_data.text)查看其内容。

有些网站具备反爬机制,这时print出来的结果可能是缺斤少两、奇奇怪怪的,这时就需要爬虫与反爬虫进行更高级的智斗了。所幸酷狗网页并没有反爬机制,我们可以很愉快地获取网页内容。

插一句,如果要爬取国外的网站,得先保证网络能够使浏览器正常访问网站,没有vpn的话可能会报错。

3. HTML解析

但是,我们得到的html文档内容太复杂了,真是看得人头大,我们怎样才能从这些奇怪的标记中找到我们需要的信息呢?

这时就该BeautifulSoup库派上用场啦,它可以对HTML/XML文档进行解析,将网页源代码解析为Soup文档,以便过滤提取数据。

1
2
from bs4 import BeautifulSoup
soup = BeautifulSoup(wb_data.text,'html.parser')

这时再进行print(soup.prettify())可以看到解析后的Soup文档,看上去与原来的html文档没什么不同,但通过BeautifulSoup解析得到的Soup文档按章标准缩进格式的结构输出,为结构化数据的过滤提取做好准备。

4. 数据提取

终于到最重要的数据提取了。我们需要的数据到底在哪里?我们怎样把它们提取出来?

这里以提取“歌曲名称”为例,用chrome浏览器开发者工具中的“检查元素”功能,我们可以找到歌曲名称属标签在html文档的位置。鼠标右击标签,选择复制selector,这就是“歌曲名称”所属标签在html中的定位(好像也是用CSS制作样式时的定位方式)。

注意:将li:nth-child(1)中的伪类删去,即改为li,以获得整个页面22个歌曲名称。

接着我们就可以用BeautifulSoup中的select()方法找到“歌曲名称”在Soup文档中的位置,用get_text()方法获取title属性中的文本(也可以用get()方法获取其他属性值),再进行字符串处理,就可以得到“歌曲名称”。

1
2
3
4
5
6
titles = soup.select('#rankWrap > div.pc_temp_songlist > ul > li > a')
for title in titles:
data = {
'song':title.get_text(strip=True).split('-')[0]
}
print(data)

注:这里发现,在html中,title属性值为“歌手-歌曲名称”,但在使用方法get_text()后,提取出内容为“歌曲名称-歌手”。目前不清楚原因,之后可能要去翻阅下官方文档。

5. 导入Excel

最后我们将提取到的数据导入到Excel表格中。这里只需要用到openpyxl库,就能够轻松实现工作簿编辑。

1
2
3
4
5
6
7
8
from openpyxl import Workbook
workbook = Workbook()
sheet = workbook.active
row = 0
for title in titles:
row += 1
sheet['A'+str(row)].value = title.get_text(strip=True).split('-')[0]
workbook.save('songs_TOP500.xlsx')

运行后发现当前目录下出现一个名为“songs_TOP500.xlsx”的xlsx文件,工作表中A列记录了歌曲名称。

6. 最终代码与运行结果

6.1 在最终代码前

基本工作已经完成,现在只需注意两点:

  1. TOP500在23个网页html上,需根据url特点构造url列表,爬取这23个页面;

  2. 每次爬取网页需暂停0.5~1s,防止请求过快,触发网站的反爬程序

6.2 最终代码(仅供参考)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# 2022.9.28
# 根据参考书上样例爬取酷狗Top500的歌手、歌名和歌曲时长等信息

# 必要库调用
import requests
from bs4 import BeautifulSoup
from openpyxl import Workbook
import time

# 伪装浏览器请求头
headers = {
'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0Safari/537.36"
}
workbook = Workbook()
sheet = workbook.active
columns = ['A','B','C','D']
row = 0


# 定义获取信息的函数
def get_info(url):
# 爬取网页
wb_data = requests.get(url, headers=headers)
soup = BeautifulSoup(wb_data.text, 'html.parser')
# 提取信息
ranks = soup.select('#rankWrap > div.pc_temp_songlist > ul > li > span.pc_temp_num')
titles = soup.select('#rankWrap > div.pc_temp_songlist > ul > li > a')
times = soup.select('#rankWrap > div.pc_temp_songlist > ul > li > span.pc_temp_tips_r > span')

# 调整输出
for rank, title, time in zip(ranks, titles, times):
data1 = rank.get_text().strip()
data2 = title.get_text(strip=True).split('-')[1]
data3 = title.get_text(strip=True).split('-')[0] # 发现get_text()后,歌手和歌名顺序颠倒,原因未知
data4 = time.get_text().strip()
listemp = [data1,data2,data3,data4]
data = {
'rank': data1,
'singer': data2,
'song': data3,
'time': data4
}
print(data)
#写入Excel
global row
row += 1
for col, temp in zip(columns, listemp):
sheet[col+str(row)].value = temp


# 程序主入口
if __name__ == '__main__':
urls = ['https://www.kugou.com/yy/rank/home/{}-8888.html'.format(str(i))
for i in range(1, 24)]
for url in urls:
get_info(url)
time.sleep(0.5)
workbook.save('songs_TOP500.xlsx')

6.3 运行结果

7. 参考文献

[1]罗攀,蒋仟.《从零开始学python网络爬虫》.机械工业出版社.2017:1-44

[2]Python 爬虫并且将数据写入Excel

[3]openpyxl库官方文档


用Python爬取网络数据到Excel
https://huigg296.github.io/post/2022092600.html
作者
huigg
发布于
2022年9月26日
许可协议