1、初次试探
接到任务,要爬取阿里云上所有拍卖的域名。本想试试scrapy,查看了下网页源码,没有找到要爬取的内容。大网站就是不一样啊,数据隐藏的这么深。
2、深入分析
从源码没看出蛛丝马迹,习惯性地打开了Chrome的调试界面,看看我提交请求时到底干了些啥,果然,露馅了!
原来域名列表是用js在前端渲染的,而不是在后端渲染的,用到了jsonp技术,用来解决Ajax跨域问题。点击search?fetchSearch…这个链接看个究竟:
原来数据是从domainapi.aliyun.com这个服务器获取的,还有个特殊的请求头:authority,内容为domainapi.aliyun.com。点击下“Response”,内容截图如下:
把内容复制到Sublime中,对比网页内容,的确是我需要爬取的数据。
3、有办法了
通过上面的研究,我已经知道如何爬取数据了。伪装浏览器调用接口直接抓取,而不是传统的解析网页这种方式。我用Firefox的HTTPRequester插件试了下,发现authority这个请求头是关键,如果不带这个请求头,则没有数据返回。保险起见,Cookie、User-Agent、Referer这几个请求头也带上,这样我们的爬虫程序跟用户用浏览器操作就几乎一模一样了。
原项目中已经有用到php的curl扩展来调用远程接口获取数据的函数,于是就用curl来抓取。请求参数根据项目需求来设置。处于保密考虑,代码就不公开了。其实抓取数据的整个HTTP过程在Chrome调试窗口中都可以看到,查阅下curl文档便能很快写出程序。抓取到的是json数据,很容易解析、入库。实际过程中如果是连续抓取,最好每次请求间隔随机0.5到1.0秒,不然怕露出马脚,被阿里云封ip。
4、经验总结
Chrome浏览器的调试功能确实强大,分析网页时多打开看看,对于分析网页在浏览器的行为和服务器的行为非常有用。
demo:
url https://www.aliyun.com/price/product?spm=5176.7921785.762131.price4.58ec4100bX3vYv#/oss/detail
py文件
import requests import json ''' 1 https://buy.aliyun.com/ajax/CalculatorAjax/Product.jsonp?callback=jQuery1113011372632283758244_1536562364999&commodity_code=oss&spec_code=oss&_=1536562365009 ''' url_1 = 'https://buy.aliyun.com/ajax/CalculatorAjax/Product.jsonp?callback=jQuery1113011372632283758244_1536562364999&commodity_code=oss&spec_code=oss&_=1536562365009' headers = { 'content-type': 'application/javascript;charset=UTF-8', 'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8', 'cookie': 'cnz=/5RDE4w/7FYCAURp6T1y/Rq9; cna=VWlDE79w6zoCAT3paUSAYvUJ; UM_distinctid=16270f0a0c13e7-0e2a6b3f357c31-414f0120-15f900-16270f0a0c238a; _ga=GA1.2.748408075.1522312969; aliyun_choice=CN; login_aliyunid_pk=1404219454986883; aliyun_site=CN; consoleRecentVisit=ecs; buy_session_id=VM566DB1-JN0YY2QLVMF5KL1JZVHN1-RMBTPRLJ-K191; buy0=1AbLByOMHeZe3G41KYd5WRQKivyheOKEPbbAe%2Fhmro2tC8TIMMn22fQf%2BT0rycPVrIqjt4EUuWEC%2BocWkcdWe4%2BDHYWnUZeqXHCdnlN6BOgZ2KaUOw0oioWMvBHLPVYLt2daKaVsDnkYxlGiBlfR7w%3D%3D; login_aliyunid_csrf=_csrf_tk_1391536560895939; isg=BC8v8ZV7qDAZ5q0mluTPwEL6vkOVxOW90Nb_i0G8yx6lkE-SSaQTRi1mFsAL6Ftu', 'referer': 'https://www.aliyun.com/price/product?spm=5176.7921785.762131.price4.58ec4100bX3vYv', 'user-agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36', } resp = requests.get(url=url_1,headers=headers) text = resp.text.lstrip('jQuery1113011372632283758244_1536562364999(').rstrip(');') text = json.loads(text) print(text)
结果:
{'data': {'config': {'jump_restrict': {'value': 'false'}, 'aliyun_chargetype': {'value': 'POSTPAY'}, 'aliyun_bill': {'value': '按使用量后付费基础上提供资源包预付费'}, 'articleProductCode': {'value': 'oss'}, 'aliyun_billing': {'value': '存储量,流量,请求次数'}, 'aliyun_agreement': {'value': 'https://help.aliyun.com/document_detail/31821.html'}, 'aliyun_billingli