爬取豆瓣遇到的问题

来源:互联网 发布:java 线程状态 编辑:程序博客网 时间:2024/06/05 09:28

最近需要爬取豆瓣的用户评分数据构造一个数据集,但是在爬取时却出了问题:
豆瓣封IP,白天一分钟可以访问40次,晚上一分钟可以访问60次,超过限制次数就会封IP。
于是,我便去代理IP网站上找了几个代理IP,但是爬取时又碰到了问题,明明已经使用代理IP,但是一旦超过限制次数爬虫仍然不能正常访问豆瓣。
问题出在Cookie上
豆瓣利用封IP+封Cookie来限制爬虫,因此只用代理IP的话也不行,Cookie也要更换。
想法一:
每次使用代理IP时,先访问豆瓣官网获取Cookie再访问用户的评论页面。本以为换了IP,Cookie随之也会更换,其实Cookie并没有改变。
想法二:
伪造Cookie。
观察豆瓣设置的Cookie格式,并进行伪造。

>>> import requests>>> r = requests.get('https://www.douban.com/')print(r.cookies)<RequestsCookieJar[<Cookie bid=UTM5r4DvtLY for .douban.com/>, <Cookie ll="118237" for .douban.com/>]>

下图是第一次访问豆瓣官网时,豆瓣建立Cookie的格式。如果已经访问过,可以把Cookie的信息删除再访问。
这里写图片描述
然后,根据Set-Cookie的格式构造Cookie就行了。
先胡乱构造一个Cookie试试:

import requestsjar = requests.cookies.RequestsCookieJar()jar.set('tasty_cookie', 'yum', domain='.douban.com', path='/cookies')url = 'https://book.douban.com/people/122624856/collect'r = requests.get(url, cookies=jar)print(r.text)

运行结果:

<html><head><title>403 Forbidden</title></head><body bgcolor="white"><center><h1>403 Forbidden</h1></center><hr><center>nginx</center></body></html>

按照豆瓣的格式来构造Cookie:

import requestsjar = requests.cookies.RequestsCookieJar()jar.set('bid', 'ehjk9OLdwha', domain='.douban.com', path='/')jar.set('11', '25678', domain='.douban.com', path='/')url = 'https://book.douban.com/people/122624856/collect'r = requests.get(url, cookies=jar)print(r.text)

运行结果:

<!DOCTYPE html><html lang="zh-cmn-Hans" class=" book-new-nav"><head>  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">  <title>  北渺读过的书(175)</title><script>!function(e){var o=function(o,n,t){var c,i,r=new Date;n=n||30,t=t||"/",r.setTime(r.getTime()+24*n*60*60*1e3),c="; expires="+r.toGMTString();for(i in o)e.cookie=i+"="+o[i]+c+"; path="+t},n=function(o){var n,t,c,i=o+"=",r=e.cookie.split(";");for(t=0,c=r.length;t<c;t++)if(n=r[t].replace(/^\s+|\s+$/g,""),0==n.indexOf(i))return n.substring(i.length,n.length).replace(/\"/g,"");return null},t=e.write,c={"douban.com":1,"douban.fm":1,"google.com":1,"google.cn":1,"googleapis.com":1,"gmaptiles.co.kr":1,"gstatic.com":1,"gstatic.cn":1,"google-analytics.com":1,"googleadservices.com":1},i=function(e,o){var n=new Image;n.onload=function(){},n.src="https://www.douban.com/j/except_report?kind=ra022&reason="+encodeURIComponent(e)+"&environment="+encodeURIComponent(o)},r=function(o){try{t.call(e,o)}catch(e){t(o)}},a=/<script.*?src\=["']?([^"'\s>]+)/gi,g=/http:\/\/(.+?)\.([^\/]+).+/i;e.writeln=e.write=function(e){var t,l=a.exec(e);return l&&(t=g.exec(l[1]))?c[t[2]]?void r(e):void("tqs"!==n("hj")&&(i(l[1],location.href),o({hj:"tqs"},1),setTimeout(function(){location.replace(location.href)},50))):void r(e)}}(document);</script>...

这样就能解决限制爬取的问题了。