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

网络爬虫(二) 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()

运行效果如下:
运行效果

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

猜你喜欢

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