抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

beautifulSoup 可以很方便的获取 html 页面的标签节点,而且也很容易获取到标签的属性和文本内容。我们就运用 beautifulSoup 来爬取同步加载页面数据,然后我们将获取到的数据存入到 excel 中。

爬取同步加载页面数据

我们这里爬取豆瓣电影Top 250 的数据做描述,request库请求页面,beautifulSoup用来获取页面节点,所使用到的库自行安装。

获取页面源码

1
2
3
4
5
6
7
8
9
10
11
from urllib import request
from chardet import detect
from bs4 import BeautifulSoup


def get_soup(page_url):
"""获取源码"""
with request.urlopen(page_url) as fp:
byt = fp.read()
det = detect(byt)
return BeautifulSoup(byt.decode(det['encoding']), 'lxml')

page_url为页面地址,lxmlpython库自行安装。

获取页面数据

我们运用beautifulSoup来获取页面的数据,数据一般存放在页面的节点内容中(如:标题、价格、数量)和节点的属性中(图片链接),所以我们需要找到这些存放数据的相应节点。

douban电影top250数据节点

我们需要从中找到一些规律,每部电影的数据都存放在一个li中,所有的li都存放在一个ol中,图片的链接在liimg标签的src属性中,其他的数据都放在带有class属性的span标签中。

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
# 正则式
import re

def get_data(page):
"""
获取数据
selelct 可以用css语法获取标签,find可以获取标签里的 attrs 属性值
"""
data = []
ol = page.find('ol', attrs={'class': 'grid_view'})
for li in ol.select('li'):
# 单元
tmp = []
# 多个 title
titles = []
img_url = li.find('img').attrs['src'].strip()
tmp.append(img_url)
for span in li.findAll('span', attrs={"class": re.compile('')}):
if span.attrs['class'][0] == 'title':
titles.append(span.string.strip())
# 评价
if span.attrs['class'][0] == 'rating_num':
tmp.append(span.string.strip())
# 简评
if span.attrs['class'][0] == 'inq':
tmp.append(span.string.strip())
tmp.insert(0, titles)
data.append(tmp)
return data

获取下一页的数据

我们先需要在页面中找到下一页数据请求的参数
下一页按钮
我们可以看到下一页的参数为?start=25&filter=,所以获取到这个参数然后加入到之前的网址当中,获取到的数据就是下一页的数据了。

1
2
3
4
5
6
7
def next_url(page):
"""获取下一页链接后缀"""
a = page.find('a', text=re.compile("^后页"))
if a:
return a.attrs['href']
else:
return None

保存数据到 excel 中

1
2
3
4
5
6
7
8
9
10
import xlwt

def xls_save(workbook, data, count):
"""保存数据到excel"""
for d in data:
for i in range(len(d)):
# print(d[i])
workbook.write(count, i, d[i])
count = count + 1
return workbook, count

xlwtpython库自行安装,workbook为要保存的excel对象,databeautifulSoup对象,count为要写入数据的行数。

完整代码

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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# 爬取豆瓣电影 top250

from urllib import request
from chardet import detect
from bs4 import BeautifulSoup
import re
import xlwt
import os


def get_soup(page_url):
"""获取源码"""
with request.urlopen(page_url) as fp:
byt = fp.read()
det = detect(byt)
return BeautifulSoup(byt.decode(det['encoding']), 'lxml')


def get_data(page):
"""
获取数据
selelct 可以用css语法获取标签,find可以获取标签里的 attrs 属性值
"""
data = []
ol = page.find('ol', attrs={'class': 'grid_view'})
for li in ol.select('li'):
# 单元
tmp = []
# 多个 title
titles = []
img_url = li.find('img').attrs['src'].strip()
tmp.append(img_url)
for span in li.findAll('span', attrs={"class": re.compile('')}):
if span.attrs['class'][0] == 'title':
titles.append(span.string.strip())
if span.attrs['class'][0] == 'rating_num':
tmp.append(span.string.strip())
if span.attrs['class'][0] == 'inq':
tmp.append(span.string.strip())
tmp.insert(0, titles)
data.append(tmp)
return data


def next_url(page):
"""获取下一页链接后缀"""
a = page.find('a', text=re.compile("^后页"))
if a:
return a.attrs['href']
else:
return None


def xls_save(workbook, data, count):
"""保存数据到excel"""
for d in data:
for i in range(len(d)):
# print(d[i])
workbook.write(count, i, d[i])
count = count + 1
return workbook, count


if __name__ == '__main__':
url = 'https://movie.douban.com/top250'
soup = get_soup(url)
# print(get_data(soup))
path = os.path.join(os.getcwd() + "\\" + "douban-top250.xls")
xls_file = os.path.exists(path)
if xls_file:
os.remove(path)
wb = xlwt.Workbook(encoding='utf-8')
xls = wb.add_sheet('top250')
head = ['标题', '图片地址', '评分', '简评'] # 表头
row = 1
for h in range(len(head)):
xls.write(0, h, head[h])
xls, row = xls_save(xls, get_data(soup), 1)
nxt = next_url(soup)
while nxt:
soup = get_soup(url + nxt)
xls, row = xls_save(xls, get_data(soup), row)
nxt = next_url(soup)
wb.save('douban-top250.xls')

评论