实现简单小爬虫,爬取斗鱼直播页面所有当前在线直播列表信息
文章目录
1 目标分析2 分析URL2.1 分析首页URL2.2 分析换页URL2.3 确定爬取URL
3 代码4 总结
1 目标分析
爬取斗鱼直播页面所有当前在线直播列表信息,包括房间标题、主播名、所属类别、热度等信息。
2 分析URL
2.1 分析首页URL
打开斗鱼直播https://www.douyu.com/directory/all 很容易发现,通过https://www.douyu.com/directory/all链接打开网页时,浏览器加载的第一个文件(all)包含了页面上的所需的数据,JSS和CSS仅修改页面显示及动画,未修改数据。该请求获取的文件可能是缓存服务器中的数据。
2.2 分析换页URL
通过点击页2,发现浏览器地址栏URL没有发生改变,由此可知,换页操作是AJAX请求。 在加载的文件中,可以找到一个文件名为“2”的文件,包含JSON数据,其内容与页面直播信息一致,且其中’pgcnt’对应的值与最大页面数相同。 查看文件“2”的请求头信息,得到AJAX请求的URLhttps://www.douyu.com/gapi/rkc/directory/0_0/2 点击页3,也很容易就找到文件名为“3”的文件,其请求URL为https://www.douyu.com/gapi/rkc/directory/0_0/3,与“2”的请求URL差别仅在最后“/数字”的区别。
点击末页,会得到类似的结果。
再回头点击页1,发现也是AJAX请求,得到文件名为“1”的json文件,其请求URL为https://www.douyu.com/gapi/rkc/directory/0_0/1
2.3 确定爬取URL
由以上分析可以推断出,换页操作是AJAX请求,请求URL为:https://www.douyu.com/gapi/rkc/directory/0_0/num,num为对应页面数。 URL未加密,变化规律简单。
3 代码
import json
import requests
class DouyuSpider:
def __init__(self
):
""" 初始化DouyuSpider
创建一个斗鱼直播页面爬虫
"""
self
.headers
= {
'User-Agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36',
}
self
.start_url
= 'https://www.douyu.com/gapi/rkc/directory/0_0/{:d}'
def fetch_one_page(self
, offset
):
""" 发起请求,获取响应数据
:param offset: 页面序号
:return response.content: 二进制响应体数据
"""
response
= requests
.get
(
self
.start_url
.format(offset
),
headers
=self
.headers
)
return response
.content
def parse_json(self
, content
):
"""解析数据
:param content: 响应体二进制数据
:return items, pgcnt: 直播信息列表,当前最大页面数
"""
results
= json
.loads
(content
.decode
())['data']
items
= []
num
= 0
for result
in results
['rl']:
item
= {}
item
['topic'] = result
['c2name']
item
['title'] = result
['rn']
ol
= result
['ol'] / 10000
if ol
== 0:
item
['hot'] = '0'
else:
item
['hot'] = f
'{ol:.1f}万'
item
['user'] = result
['nn']
item
['room_url'] = 'https://www.douyu.com/{}'.format(result
['url'])
items
.append
(item
)
num
+= 1
if num
% 20 == 0:
print(f
'完成第{num}条数据')
print(item
)
return items
, int(results
['pgcnt'])
def save_content(self
, items
):
""" 保存数据
:param items: 直播信息列表
:return None:
"""
with open('douyu.json', 'a+', encoding
='utf-8') as f
:
for data
in items
:
json
.dump
(data
, f
, ensure_ascii
=False)
f
.write
('\n')
def is_next(self
, max_pages
, offset
):
""" 判断是否有下一页
:param max_pages: 当前最大页面数
:param offset: 已爬取页数
:return next_flag: 是否有下一页
"""
if offset
< max_pages
:
next_flag
= True
if offset
>= max_pages
:
next_flag
= False
return next_flag
def run(self
):
""" 运行爬虫
开始爬取数据
"""
offset
= 0
next_flag
= True
while next_flag
:
offset
+= 1
html
= self
.fetch_one_page
(offset
)
items
, max_pages
= self
.parse_json
(html
)
self
.save_content
(items
)
print('*'*10 + f
'完成第{offset}页' + '*'*10)
print(f
'最大页数{max_pages}')
next_flag
= self
.is_next
(max_pages
, offset
)
print('已爬取所有页面')
if __name__
== '__main__':
dou_spider
= DouyuSpider
()
dou_spider
.run
()
4 总结
AJAX请求URL没有加密,所以非常容易获取服务器返回的JSON数据,解析JSON数据就能得到所需要的数据。