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

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

2.2 find_all爬取酷狗top500

我们利用selector方法对酷狗top500进行了爬取,但此方法提取数据很不健壮,当对方对html源码修改进行修改,这个爬虫就不能使用了,因为这方法是按照 html 树一层一层元素的选取,当有一个元素修改,树状结构发生变化,就不再可用。
这里我们使用 find_all 方法提取数据,就如字面意思,找到所有符合的元素,这种方法比 select 更健壮,因为不管 html 树状结构如何改变,此方法都会选择特定的元素而不受 html 树状结构的影响。

2.2.1 环境配置

Selector方法中我们安装了bs4和requests库,这次我们还需另一个库——lxml。
打开 cmd 命令行(win + r)
输入 pip install lxml 完成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()

运行效果如下:
运行效果

发布了4 篇原创文章 · 获赞 9 · 访问量 506

猜你喜欢

转载自blog.csdn.net/hxy18219110128/article/details/105180837