python bs4 find_all_网络爬虫(三)BS4提取之find_all

我们用selector方法对酷狗top500进行爬取,此方法提取数据很不健壮,当对方对html源码修改进行修改,这个爬虫就不能使用了,因为这方法是按照 html 树一层一层元素的选取,当有一个元素修改,树状结构发生变化,就不再可用。

这里我们使用 find_all 方法提取数据,就如字面意思,找到所有符合的元素,这种方法比 select 更健壮,因为不管 html 树状结构如何改变,此方法都会选择特定的元素而不受 html 树状结构的影响。

2.2.1 环境配置

Selector方法中我们安装了bs4和requests库,这次我们还需另一个库——lxml。

打开 cmd 命令行(win + r)

输入 pip install lxml 完成lxml库的安装。

2.2.2 解析html

在selector中我们运行的代码是:html = BeautifulSoup(html)

现在我们将代码修改为:html = BeautifulSoup(html,'lxml')

第一个参数是请求响应返回的 html 源码;第二个参数是解析器的选择,当然选择器不止 lxml,选择 lxml 是比较适合的选择,它解析速度快,因为底层是 c 语言封装的,解析准确,所以推荐大家一般情况下使用它

2.2.3数据提取

在selector中我们的提取代码为:

ranks = html.select('#rankWrap > div.pc_temp_songlist > ul > li > span.pc_temp_num')

names = html.select('#rankWrap > div.pc_temp_songlist > ul > li > a')

times = html.select('#rankWrap > div.pc_temp_songlist > ul > li > span.pc_temp_tips_r > span')

现在我们将其中的select修改为find_all方法即可

ranks = html.find_all('span',class_='pc_temp_num')

names = html.find_all('a',class_='pc_temp_songname')

times = html.find_all('span',class_='pc_temp_time')

右击元素中检查,我们可以知道元素的对应标签和类名,也就是我们的第一个参数和第二个参数,find_all(标签名,class_=类名)

我们来看看排名的标签如下:

可以看到它的标签名为span,class属性名为pc_temp_num,所以写为:ranks = html.find_all('span',class_='pc_temp_num')

2.2.4 find_all方法总结

修改的部分在上面已经进行讲解,其余的部分和selector中不做改动

代码如下:

import requests

import time

from bs4 import BeautifulSoup

import lxml

def get_html(url):

headers = {

'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/53\7.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36'

}

response = requests.get(url, headers=headers)

if response.status_code == 200:

return response.text

else:

return

def get_infos(html):

html = BeautifulSoup(html,'lxml')

# 排名

ranks = html.find_all('span',class_='pc_temp_num')

# 歌手、歌名

names = html.find_all('a',class_='pc_temp_songname')

# 播放时间

times = html.find_all('span',class_='pc_temp_time')

for r,n,t in zip(ranks,names,times):

r = r.get_text().replace('\n','').replace('\t','').replace('\r','')

n = n.get_text()

t = t.get_text().replace('\n','').replace('\t','').replace('\r','')

data = {

'排名': r,

'歌名-歌手': n,

'播放时间': t

}

print(data)

def main():

urls = ['https://www.kugou.com/yy/rank/home/{}-8888.html?from=rank'

.format(str(i)) for i in range(1, 24)]

for url in urls:

html = get_html(url)

get_infos(html)

time.sleep(1)

if __name__ == '__main__':

main()

运行效果如下:

欢迎大家加入人工智能圈参与交流人工智能学习圈 - 知乎​www.zhihu.com

你可能感兴趣的:(python,bs4,find_all)