【轉】Python使用urllib2寫爬蟲抓站的一些技巧

1.最基本的抓站

import urllib2 
content = urllib2.urlopen('http://XXXX').read()

2.使用代理服務器

這在某些狀況下比較有用,好比IP被封了,或者好比IP訪問的次數受到限制等等。正則表達式

import urllib2 
proxy_support = urllib2.ProxyHandler({'http':'http://XX.XX.XX.XX:XXXX'}) 
opener = urllib2.build_opener(proxy_support, urllib2.HTTPHandler) 
urllib2.install_opener(opener) 
content = urllib2.urlopen('http://XXXX').read()

3.須要登陸的狀況

登陸的狀況比較麻煩我把問題拆分一下:瀏覽器

3.1 cookie的處理

import urllib2, cookielib 
cookie_support= urllib2.HTTPCookieProcessor(cookielib.CookieJar()) 
opener = urllib2.build_opener(cookie_support, urllib2.HTTPHandler) 
urllib2.install_opener(opener) 
content = urllib2.urlopen('http://XXXX').read() 

是的沒錯,若是想同時用代理和cookie,那就加入proxy_support而後operner改成 opener = urllib2.build_opener(proxy_support, cookie_support, urllib2.HTTPHandler)

3.2 表單的處理

登陸必要填表,表單怎麼填?首先利用工具截取所要填表的內容 好比我通常用firefox+httpfox插件來看看本身到底發送了些什麼包 這個我就舉個例子好了,以verycd爲例,先找到本身發的POST請求,以及POST表單項:服務器

能夠看到verycd的話須要填username,password,continueURI,fk,login_submit這幾項,其中fk是隨機生成的(其實不太隨機,看上去像是把epoch時間通過簡單的編碼生成的),須要從網頁獲取,也就是說得先訪問一次網頁,用正則表達式等工具截取返回數據中的fk項。continueURI顧名思義能夠隨便寫,login_submit是固定的,這從源碼能夠看出。還有username,password那就很顯然了。 好的,有了要填寫的數據,咱們就要生成postdatacookie

import urllib 
postdata=urllib.urlencode({'username':'XXXXX', 'password':'XXXXX', 'continueURI':'http://www.verycd.com/',  'fk':fk,  'login_submit':'登陸'})

而後生成http請求,再發送請求:多線程

req = urllib2.Request(url = 'http://secure.verycd.com/signin/*/http://www.verycd.com/', data = postdata ) 
result = urllib2.urlopen(req).read()

3.3 假裝成瀏覽器訪問

某些網站反感爬蟲的到訪,因而對爬蟲一概拒絕請求 這時候咱們須要假裝成瀏覽器,這能夠經過修改http包中的header來實現併發

headers = {'User-Agent':'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6' } 
req = urllib2.Request( url = 'http://secure.verycd.com/signin/*/http://www.verycd.com/', data = postdata, headers = headers )

3.4 反」反盜鏈」

某些站點有所謂的反盜鏈設置,其實說穿了很簡單,就是檢查你發送請求的header裏面,referer站點是否是他本身,因此咱們只須要像3.3同樣,把headers的referer改爲該網站便可,以黑幕著稱地cnbeta爲例:函數

headers = { 'Referer':'http://www.cnbeta.com/articles' }

3.5 終極絕招

有時候即便作了3.1-3.4,訪問仍是會被據,那麼沒辦法,老老實實把httpfox中看到的headers全都寫上,那通常也就好了。工具

再不行,那就只能用終極絕招了,selenium直接控制瀏覽器來進行訪問,只要瀏覽器能夠作到的,那麼它也能夠作到。相似的還有pamie,watir,等等等等。post

4.多線程併發抓取

單線程太慢的話,就須要多線程了,這裏給個簡單的線程池模板 這個程序只是簡單地打印了1-10,可是能夠看出是併發地。網站

from threading import Thread 
from Queue import Queue 
from time import sleep 
#q是任務隊列 
#NUM是併發線程總數 
#JOBS是有多少任務 
q = Queue() 
NUM = 2 
JOBS = 10 
#具體的處理函數,負責處理單個任務 
def do_somthing_using(arguments):
    print arguments #這個是工做進程,負責不斷從隊列取數據並處理 def working():
    while True:     
        arguments = q.get()     
        do_somthing_using(arguments)         
        sleep(1)         
        q.task_done() #fork NUM個線程等待隊列 
for i in range(NUM):
    t = Thread(target=working)     
    t.setDaemon(True)     
    t.start() #把JOBS排入隊列 
for i in range(JOBS):     
    q.put(i) #等待全部JOBS完成 
    q.join()
相關文章
相關標籤/搜索