用python爬虫抓站的一些技巧.docx
用PYTHON爬虫抓站的一些技巧总结收藏人20130305|阅转||分享学用PYTHON也有3个多月了,用得最多的还是各类爬虫脚本写过抓代理本机验证的脚本,写过在DISCUZ论坛中自动登录自动发贴的脚本,写过自动收邮件的脚本,写过简单的验证码识别的脚本,本来想写GOOGLEMUSIC的抓取脚本的,结果有了强大的GMBOX,也就不用写了。这些脚本有一个共性,都是和WEB相关的,总要用到获取链接的一些方法,再加上SIMPLECD这个半爬虫半网站的项目,累积不少爬虫抓站的经验,在此总结一下,那么以后做东西也就不用重复劳动了。1最基本的抓站IMPORTURLLIB2CONTENTURLLIB2URLOPEN HTTP//XXXX READ2使用代理服务器这在某些情况下比较有用,比如IP被封了,或者比如IP访问的次数受到限制等等。IMPORTURLLIB2PROXY_SUPPORTURLLIB2PROXYHANDLER{ HTTP HTTP//XXXXXXXXXXXX }OPENERURLLIB2BUILD_OPENERPROXY_SUPPORT,URLLIB2HTTPHANDLERURLLIB2INSTALL_OPENEROPENERCONTENTURLLIB2URLOPEN HTTP//XXXX READ3需要登录的情况登录的情况比较麻烦我把问题拆分一下31COOKIE的处理IMPORTURLLIB2,COOKIELIBCOOKIE_SUPPORTURLLIB2HTTPCOOKIEPROCESSORCOOKIELIBCOOKIEJAROPENERURLLIB2BUILD_OPENERCOOKIE_SUPPORT,URLLIB2HTTPHANDLERURLLIB2INSTALL_OPENEROPENERCONTENTURLLIB2URLOPEN HTTP//XXXX READ是的没错,如果想同时用代理和COOKIE,那就加入PROXY_SUPPORT然后OPERNER改为OPENERURLLIB2BUILD_OPENERPROXY_SUPPORT,COOKIE_SUPPORT,URLLIB2HTTPHANDLER32表单的处理登录必要填表,表单怎么填首先利用工具截取所要填表的内容。比如我一般用FIREFOXHTTPFOX插件来看看自己到底发送了些什么包这个我就举个例子好了,以VERYCD为例,先找到自己发的POST请求,以及POST表单项可以看到VERYCD的话需要填USERNAME,PASSWORD,CONTINUEURI,FK,LOGIN_这几项,其中FK是随机生成的(其实不太随机,看上去像是把EPOCH时间经过简单的编码生成的),需要从网页获取,也就是说得先访问一次网页,用正则表达式等工具截取返回数据中的FK项。CONTINUEURI顾名思义可以随便写,LOGIN_是固定的,这从源码可以看出。还有USERNAME,PASSWORD那就很显然了。好的,有了要填写的数据,我们就要生成POSTDATAIMPORTURLLIBPOSTDATAURLLIBURLENCODE{ USERNAME XXXXX , PASSWORD XXXXX , CONTINUEURI HTTP//WWWVERYCDCOM/ , FK FK, LOGIN_ 登录 }然后生成HTTP请求,再发送请求REQURLLIB2REQUESTURL HTTP//SECUREVERYCDCOM/SIGNIN//HTTP//WWWVERYCDCOM/ ,DATAPOSTDATARESULTURLLIB2URLOPENREQREAD33伪装成浏览器访问某些网站反感爬虫的到访,于是对爬虫一律拒绝请求。这时候我们需要伪装成浏览器,这可以通过修改HTTP包中的HEADER来实现HEADERS{ USERAGENT MOZILLA/50WINDOWSUWINDOWSNT61ENUSRV1916GECKO/20091201FIREFOX/356 }REQURLLIB2REQUESTURL HTTP//SECUREVERYCDCOM/SIGNIN//HTTP//WWWVERYCDCOM/ ,DATAPOSTDATA,HEADERSHEADERS34反”反盗链”某些站点有所谓的反盗链设置,其实说穿了很简单,就是检查你发送请求的HEADER里面,REFERER站点是不是他自己,所以我们只需要像33一样,把HEADERS的REFERER改成该网站即可,以黑幕著称地CNBETA为例HEADERS{ REFERER HTTP//WWWCNBETACOM/ARTICLES }HEADERS是一个DICT数据结构,你可以放入任何想要的HEADER,来做一些伪装。例如,有些自作聪明的网站总喜欢窥人隐私,别人通过代理访问,他偏偏要读取HEADER中的XFORWARDEDFOR来看看人家的真实IP,没话说,那就直接把XFORWARDEFOR改了吧,可以改成随便什么好玩的东东来欺负欺负他,呵呵。35终极绝招有时候即使做了3134,访问还是会被据,那么没办法,老老实实把HTTPFOX中看到的HEADERS全都写上,那一般也就行了。再不行,那就只能用终极绝招了,SELENIUM直接控制浏览器来进行访问,只要浏览器可以做到的,那么它也可以做到。类似的还有PAMIE,WATIR,等等等等。4多线程并发抓取单线程太慢的话,就需要多线程了,这里给个简单的线程池模板这个程序只是简单地打印了110,但是可以看出是并发地。FROMTHREADINGIMPORTTHREADFROMQUEUEIMPORTQUEUEFROMTIMEIMPORTSLEEPQ是任务队列NUM是并发线程总数JOBS是有多少任务QQUEUENUM2JOBS10具体的处理函数,负责处理单个任务DEFDO_SOMTHING_USINGARGUMENTSPRINTARGUMENTS这个是工作进程,负责不断从队列取数据并处理DEFWORKINGWHILETRUEARGUMENTSQGETDO_SOMTHING_USINGARGUMENTSSLEEP1QTASK_DONEFORKNUM个线程等待队列FORIINRANGENUMTTHREADTARGETWORKINGTSETDAEMONTRUETSTART把JOBS排入队列FORIINRANGEJOBSQPUTI等待所有JOBS完成QJOIN5验证码的处理碰到验证码咋办这里分两种情况处理GOOGLE那种验证码,凉拌简单的验证码字符个数有限,只使用了简单的平移或旋转加噪音而没有扭曲的,这种还是有可能可以处理的,一般思路是旋转的转回来,噪音去掉,然后划分单个字符,划分好了以后再通过特征提取的方法例如PCA降维并生成特征库,然后把验证码和特征库进行比较。这个比较复杂,一篇博文是说不完的,这里就不展开了,具体做法请弄本相关教科书好好研究一下。事实上有些验证码还是很弱的,这里就不点名了,反正我通过2的方法提取过准确度非常高的验证码,所以2事实上是可行的。6GZIP/DEFLATE支持现在的网页普遍支持GZIP压缩,这往往可以解决大量