前面有篇文章给出了爬取动态页面的一种思路,即应用Selenium+Firefox(参考《scrapy动态页面爬取》)。但是selenium需要运行本地浏览器,比较耗时,不太适合大规模网页抓取。
事实上,还有一种执行效率更高的方法。就是事先分析js发出的GET或者POST请求的网址,这样通过python向目标地址发出同样的请求,就可以得到与浏览器一致的response结果。
具体的步骤是:采用chrome浏览器中的调试工具,分析网页中用JavaScript获取数据的request语句。具体分析步骤是:打开监视工具(inspect)——网络(Network)——XHR(XMLHttpRequest),可以找到一个POST request对应的JavaScript或者ajax。接下来要做的就是直接对这个JavaScript或ajax做request操作,以获取我们想要的信息。
以下是通过发送request,获取response的代码示例:
import urllib2
import codecs
import json
#读取json中所有的pid,并且生成url list
#sessionUrl ='http://buluo.qq.com/p/detail.html?bid=254116&pid='
defgetUrlList(pContent, sessionUrl):
posts = pContent['result']['posts']
result = ["".join([sessionUrl,i['pid']]) for i in posts]
return result
url ='http://buluo.qq.com/cgi-bin/bar/post/get_post_by_page?bid=254116&num=20&start=1980&source=2'
#注意headers应当使用dict类型,以适应request.add_header(key,value)的参数要求
#Cookie:pgv_pvi=1061844992; pgv_si=s7051931648
headers ={'Host':'buluo.qq.com',
'Connection':'keep-alive',
'Accept': 'application/json',
'X-Requested-With':'XMLHttpRequest',
'User-Agent': 'Mozilla/5.0 (WindowsNT 6.1; WOW64) AppleWebKit/537.36 '+
'(KHTML, like Gecko)Chrome/50.0.2661.102 Safari/537.36',
'Referer':'http://buluo.qq.com/p/barindex.html?bid=254116',
'Accept-Language': 'zh-CN,zh;q=0.8',
}
data = None
req =urllib2.Request(url, data, headers)
response =urllib2.urlopen(req)
content =response.read().decode('utf-8')
withcodecs.open('./content.txt', 'wb', encoding = 'utf-8', errors='ignore') as f:
f.write(content)
sessionUrl ='http://buluo.qq.com/p/detail.html?bid=254116&pid='
pContent =json.loads(content);
ifpContent['result']['total'] != 0:
print getUrlList(pContent, sessionUrl)
else:
print "no contents in this page!"