网络爬虫(二) BS4提取之Selector

Tanisha ·
更新时间:2024-11-13
· 538 次阅读

网络爬虫(二) BS4提取之Selector 2.1 Selector爬取酷狗top500 2.1.1 环境配置

第一步:下载谷歌浏览器
第二步:安装bs4,requests库
打开 cmd 命令行(win + r)
输入 pip install bs4 完成bs4模块安装。
输入 pip install requests 完成requests模块安装。

2.1.2 可能遇到的安装错误

如果执行 pip install bs4 后报错为“pip 不是可执行的命令”,将pip 的路径加入环境变量即可

2.1.3 构造请求网址

提供URL如下:
https://www.kugou.com/yy/rank/home/1-8888.html?from=rank
我们观察 url 如下几个字段:
https:超文本传输协议
www.kugou.com:域名
yy/rank/home/1-8888:域名下的子网页
.html:代表此网页是静态的,后面会讲
?:问好后面的一般都是一些请求参数
打开后只能看到前 22 名的数据,如下:
前22名数据
我们可以看到,其中有一个 1-8888 这个参数,打开上述网址后我们只能看到前 22 首歌,如果需要查看更多内容可以下载客户端,但是这里我们把 1-8888 改成 2-8888其实也是可以实现翻页的效果,如下:
翻页
我们可以根据排名共有500条记录可以知道一共有23页:
最后一页
到这里我们我们需要提取的数据就知道在哪里了。
在知道了有多少页以及 url 的含义后,通过以下代码构造所有的 url:

urls = ['https://www.kugou.com/yy/rank/home/{}-8888.html?from=rank'.format(str(i)) for i in range(1, 24)]

我们需要的所有url就都包含在urls中了

2.1.4构造请求头

一般浏览器都会有反爬机制,用来区别是人还是机器访问的一种手段。我们设置请求头为浏览器的请求头,以模拟成人为的访问,当然这只是最简单的一种防反爬的手段,一般我们都会带上,代码如下:

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'}

这个headers是先通过人为访问,在headers中的user-agent找到:
user-agent

2.1.5 请求访问网页 response = requests.get(url, headers=headers) if response.status_code == 200: return response.text else: return response = requests.get(url, headers=headers)

使用 requests 库的get方法访问网页,第一个参数为网址,第二个参数为请求头,返回值里面有很多结果,包括有状态响应码,网页源码,二进制等,赋值给我们定义的response
response.status_code == 200
status_code
调用请求结果 response 中的status_code查看请求状态码,200代表请求成功,就返回,否则返回一个 None,状态码一般有 2xx,4xx,3xx,5xx,分别代表请求成功,客户端访问失败,重定向,服务器问题。
return response.text表示返回响应结果的text,即网页html源码
html源码

2.1.6 解析网页

在请求访问网页中我们得到了我们需要的response,其中的html源码也被我们所得到,但是这个源码比较丑陋,所以我们可以利用beautifulsoup来对源码进行煲汤。

html = BeautifulSoup(html)

返回的html

2.1.7 提取数据

在浏览器中将鼠标指向我们所需要提取的元素,右击检查后会出现对应源码,右击→copy→copy 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') 2.1.8 获得数据 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','')

用zip 函数,把对应的排名,歌名歌手,播放时间打包,打包结果为一个列表,[(排名,歌手歌名,播放时间),(排名,歌手歌名,播放时间),……]
使用 get_text() 获得实际数据

2.1.9 selector总结

这种提取方式是不会常用的,因为效果很不健壮,如果网页改了改结构,就不能使用了。
代码如下:

import requests import time from bs4 import BeautifulSoup 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) # 排名 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') # 打印信息 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()

运行效果如下:
运行效果


作者:hyhooo



爬虫 网络爬虫

需要 登录 后方可回复, 如果你还没有账号请 注册新账号