@导入类库
import requests
from lxml import etree
import json
import time
@请求地址和请求头
# 请求头,用于伪装客户端浏览器,可由抓包获取
header_base = {
'Connection': 'keep-alive',
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36',
'Upgrade-Insecure-Requests': '1',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'zh-CN,zh;q=0.9',
}
# 首页 URL
url_str = 'https://www.douyu.com/directory/all'
@发起请求,并获得html文档的页面元素树
# 获取首页信息
response = requests.get(url=url_str, headers=header_base)
# print(response.text)
# print(response.status_code)
# 获得页面的元素树
html = etree.HTML(response.text)
@解析首页信息
# 通过xpath提取房间信息:播主和在线人数
info_list = html.xpath(
"//ul[@id='live-list-contentbox']//span[@class='dy-name ellipsis fl']/text() \ | //ul[@id='live-list-contentbox']//span[@class='dy-num fr']/text()"
)
# 播主昵称
host_names = info_list[0]
print('first_name : ', host_names)
# 打印所有房间信息
for info in info_list:
print(info)
@点击首页底部的分页页码时,地址栏不会发生变化,由此我们知道该网站的分页信息是通过ajax做异步加载的
# 这里我们发现当点击第二页时,浏览器的地址栏并没有发生变化
# 无法直接从页面获取页码,因为页码是通过JS生成的
# page_num = html.xpath("//a[@class='shark-pager-item']/text()")
# print('page_num : ', page_num)
@知道了分页数据的加载地址之后,我们逐页发起请求,获取其json数据,并做分析和提取
# 该网站的分页数据是通过ajax异步加载的(无法直接从浏览器的地址栏获取其页面的URL)
# 需要借助抓包工具或页面控制台获得ajax异步请求所发送请求的url
page = 1
while True:
# 不断爬取下一页
page += 1
# 通过抓包分析获得的分页地址
url_str = 'https://www.douyu.com/gapi/rkc/directory/0_0/' + str(page)
print(url_str)
# 请求房间信息
response = requests.get(url=url_str, headers=header_base)
# print(response.text)
# 从第二页开始,数据以json格式加载,因此先将文本转换为json
info_json = json.loads(response.text)
# print(type(info_json['data']['rl']))
# 当请求的页码大于最大页码时返回的是第一页数据
# 我们以此作为循环退出条件
print('========', info_json['data']['rl'][0]['nn'],"==========")
if host_names == info_json['data']['rl'][0]['nn']:
break
# 分析json信息,循环获取每个直播房间的信息
for one_info in info_json['data']['rl']:
# 获取主播名称
host = one_info['nn']
# 获取直播在看人数
onlines = one_info['ol']
# 睡一会再接着爬下一页,以免请求过于频繁被反爬
time.sleep(2)
@爬取效果
@完整代码
import requests
from lxml import etree
import json
import time
# 请求头,用于伪装客户端浏览器,可由抓包获取
header_base = {
'Connection': 'keep-alive',
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36',
'Upgrade-Insecure-Requests': '1',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'zh-CN,zh;q=0.9',
}
# 首页 URL
url_str = 'https://www.douyu.com/directory/all'
# 获取首页信息
response = requests.get(url=url_str, headers=header_base)
# print(response.text)
# print(response.status_code)
# 获得页面的元素树
html = etree.HTML(response.text)
# 通过xpath提取房间信息:播主和在线人数
info_list = html.xpath(
"//ul[@id='live-list-contentbox']//span[@class='dy-name ellipsis fl']/text() \ | //ul[@id='live-list-contentbox']//span[@class='dy-num fr']/text()"
)
# 播主昵称
host_names = info_list[0]
print('first_name : ', host_names)
# 打印所有房间信息
for info in info_list:
print(info)
# 这里我们发现当点击第二页时,浏览器的地址栏并没有发生变化
# 无法直接从页面获取页码,因为页码是通过JS生成的
# page_num = html.xpath("//a[@class='shark-pager-item']/text()")
# print('page_num : ', page_num)
# 该网站的分页数据是通过ajax异步加载的(无法直接从浏览器的地址栏获取其页面的URL)
# 需要借助抓包工具或页面控制台获得ajax异步请求所发送请求的url
page = 1
while True:
# 不断爬取下一页
page += 30
# 通过抓包分析获得的分页地址
url_str = 'https://www.douyu.com/gapi/rkc/directory/0_0/' + str(page)
print(url_str)
# 请求房间信息
response = requests.get(url=url_str, headers=header_base)
# print(response.text)
# 从第二页开始,数据以json格式加载,因此先将文本转换为json
info_json = json.loads(response.text)
# print(type(info_json['data']['rl']))
# 当请求的页码大于最大页码时返回的是第一页数据
# 我们以此作为循环退出条件
print('========', info_json['data']['rl'][0]['nn'],"==========")
if host_names == info_json['data']['rl'][0]['nn']:
break
# 分析json信息,循环获取每个直播房间的信息
for one_info in info_json['data']['rl']:
# 获取主播名称
host = one_info['nn']
# 获取直播在看人数
onlines = one_info['ol']
# 睡一会再接着爬下一页,以免请求过于频繁被反爬
time.sleep(2)
print('OVER !!!')