目录
本人很久之前玩过这个4399的游戏(至少也上过全区榜一啊[嘚瑟]),学了Ajax请求之后试着爬了一下全区的挑战排行榜。
运行环境(jupyter notebook)
一、思路:
首先登陆火线精英官网,分析排行榜的Ajax请求,然后对每一个Ajax请求进行遍历并保存(暂时保存为list/存入MongoDB),最后使用plot绘出双y轴折线图。
二、抓取分析:
登陆官网:http://news.4399.com/hxjy/index.html,下拉至荣誉排行榜的位置,鼠标右键调出检查框,选择NetWork>XHR,刷新页面发现加载出一个Ajax请求(电信一区的挑战排行榜),如下图:
单击这个Ajax请求,可以看见,url为:http://my.4399.com/zhuanti/hxjy/ryphb-ajaxGetRank-_AJAX_-1?sid=1&aid=31,method为GET,初步来看Query参数应该是sid和aid,但是看不出参数的变化规律。另外可以看到Requests Headers的Accept,Referer,User-Agent,X-Requested-With等属性,这些在构造基本请求的时候会用到。
然后在网页上选择“电信二区”,这时发现多了一个Ajax请求,查看新请求的url:http://my.4399.com/zhuanti/hxjy/ryphb-ajaxGetRank-_AJAX_-1?sid=2&aid=31,其中参数sid=2,aid=31;选择“电信三区”,新url的sid=3,aid=31;发现sid变化而aid没有变化,推测sid代指区服,aid代指排行榜;之后切换到联通区,同理发现,联通一区:sid=101,aid=31;联通二区:sid=102,aid=31等等。
有了url,接下来分析Ajax中所需要爬取的数据。随便查看一个Ajax请求的Preview,发现“排名”,“昵称”,“难度/分数”都在data.list中。这样我们就可以获取所需数据了。
三、代码实现
1.构造单个Ajax请求
import requests
from urllib.parse import urlencode
#构造请求
base_url='http://my.4399.com/zhuanti/hxjy/ryphb-ajaxGetRank-_AJAX_-1?'
headers={
'Referer':'http://my.4399.com/zhuanti/hxjy/ryphb',
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36',
'X-Requested-With':'XMLHttpRequest'
}
#获取所需信息
def get_page(sid):
params={
'aid':31,
'sid':sid
}
url=base_url+urlencode(params)
try:
r=requests.get(url,headers=headers)
r.encoding='utf-8' #
if r.status_code==200:
return r.json()
except r.ConnectionError:
return None