python 爬蟲抓取心得

quanwei9958 轉自 python 爬蟲抓取心得分享
html

urllib.quote('要編碼的字符串')
若是你要在url請求裏面放入中文,對相應的中文進行編碼的話,能夠用:
python

urllib.quote('要編碼的字符串') web

 

query =  urllib.quote(singername)
    url = 'http://music.baidu.com/search?key='+query
    response = urllib.urlopen(url)
    text = response.read()

 

get or post  urlencodeajax

若是在GET須要一些參數的話,那咱們須要對傳入的參數進行編碼。正則表達式

 

import urllib
def url_get():
    import urllib
    params = urllib.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})
    f = urllib.urlopen("http://www.musi-cal.com/cgi-bin/query?%s" % params)
    print f.read()

def url_post():
    import urllib
    params = urllib.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})
    f = urllib.urlopen("http://www.musi-cal.com/cgi-bin/query", params)
    print f.read()

urllib urllib2 proxy 代理json

若是你請求對方的網頁,確不想被封IP的話,這個時候就要用到代理了,其實用 urllib 代理仍是比較簡單的:瀏覽器

import urllib
def url_proxy():
    proxies = {'http':'http://211.167.112.14:80'}#或者proxies = {'':'211.167.112.14:80'}
    opener = urllib.FancyURLopener(proxies)
    f = opener.open("http://www.dianping.com/shanghai")
    print f.read()

只用一個代理IP的話 有時候弄巧成拙了 剛好被大衆點評給檢測出來了
401
211.167.112.14
python-urllib/1.17
網絡


那麼就試試多個IP代理 ide

import urllib
def url_proxies():
    proxylist = (
            '211.167.112.14:80',
            '210.32.34.115:8080',
            '115.47.8.39:80',
            '211.151.181.41:80',
            '219.239.26.23:80',
            )
    for proxy in proxylist:
        proxies = {'': proxy}
        opener = urllib.FancyURLopener(proxies)
        f = opener.open("http://www.dianping.com/shanghai")
        print f.read()

這回沒問題了。

有的時候要模擬瀏覽器 ,否則作過反爬蟲的網站會知道你是robot
例如針對瀏覽器的限制咱們能夠設置User-Agent頭部,針對防盜鏈限制,咱們能夠設置Referer頭部
函數

有的網站用了Cookie來限制,主要是涉及到登陸和限流,這時候沒有什麼通用的方法,只能看可否作自動登陸或者分析Cookie的問題了。

僅僅是模擬瀏覽器訪問依然是不行的,若是爬取頻率太高依然會使人懷疑,那麼就須要用到上面的代理設置了

 

import urllib2
def url_user_agent(url):
    '''
    proxy = 'http://211.167.112.14:80'
    opener = urllib2.build_opener(urllib2.ProxyHandler({'http':proxy}), urllib2.HTTPHandler(debuglevel=1))
    urllib2.install_opener(opener)
    '''
    i_headers = {"User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.1) Gecko/20090624 Firefox/3.5",\
                 "Referer": 'http://www.dianping.com/'}
    req = urllib2.Request(url, headers=i_headers)

    return urllib2.urlopen(req).read()

#print url_user_agent('http://www.dianping.com/shanghai')

 

 就算設置了代理,代理的ip也有可能被封,還有另一種終極的辦法來防止被封,那即是使用time庫的sleep()函數。

 

import time
for i in range(1,10):
    ....#抓取邏輯
    time.sleep(5)

 

抓的地址是http://www.dianping.com/shanghai
直接抓http://www.dianping.com的話會location到城市列表去 反而達不到效果
header: Location: /citylist

 

供一段代理IP
proxylist = (
            '211.167.112.14:80',
            '210.32.34.115:8080',
            '115.47.8.39:80',
            '211.151.181.41:80',
            '219.239.26.23:80',
            '219.157.200.18:3128',
            '219.159.105.180:8080',
            '1.63.18.22:8080',
            '221.179.173.170:8080',
            '125.39.66.153:80',
            '125.39.66.151:80',
            '61.152.108.187:80',
            '222.217.99.153:9000',
            '125.39.66.146:80',
            '120.132.132.119:8080',
            '119.7.221.137:82',
            '117.41.182.188:8080',
            '202.116.160.89:80',
            '221.7.145.42:8080',
            '211.142.236.131:80',
            '119.7.221.136:80',
            '211.151.181.41:80',
            '125.39.66.131:80',
            '120.132.132.119:8080',
            '112.5.254.30:80',
            '106.3.98.82:80',
            '119.4.250.105:80',
            '123.235.12.118:8080',
            '124.240.187.79:80',
            '182.48.107.219:9000',
            '122.72.2.180:8080',
            '119.254.90.18:8080',
            '124.240.187.80:83',
            '110.153.9.250:80',
            '202.202.1.189:80',
            '58.67.147.205:8080',
            '111.161.30.228:80',
            '122.72.76.130:80',
            '122.72.2.180:80',
            '202.112.113.7:80',
            '218.108.85.59:81',
            '211.144.72.154:80',
            '119.254.88.53:8080',
            '121.14.145.132:82',
            '114.80.149.183:80',
            '111.161.30.239:80',
            '182.48.107.219:9000',
            '122.72.0.28:80',
            '125.39.68.131:80',
            '118.244.190.6:80',
            '120.132.132.119:88',
            '211.167.112.15:82',
            '221.2.80.126:8888',
            '219.137.229.214:3128',
            '125.39.66.131:80',
            '61.181.22.157:80',
            '115.25.216.6:80',
            '119.7.221.137:82',
            '221.195.42.195:8080',
            '119.254.88.53:8080',
            '219.150.254.158:8080',
            '113.9.163.101:8080',
            '222.89.154.14:9000',
            '114.141.162.53:8080',
            '218.5.74.199:3128',
            '61.152.108.187:80',
            '218.76.159.133:80',
            '59.34.57.88:8080',
            '118.244.190.34:80',
            '59.172.208.189:8080',
            '116.236.216.116:8080',
            '111.161.30.233:80',
            '220.248.237.234:8080',
            '121.14.145.132:82',
            '202.114.205.125:8080'
            )
View Code

 

Proxy的使用至關普遍,對於單個應用來講,爬蟲是很容易被封禁,若是使用Proxy模式,就能下降被封的風險,因此有需求的同窗須要仔細看下Python urllib2對於Proxy的使用:

 

 

 

抓取下拉加載或者點擊加載的頁面方法:

加載中的內容應該是ajax請求的,對付ajax請求沒有什麼好的辦法,只有抓取頁面的JS,分析JS進行抓取

解決方案:

1.傻傻的所有下拉完 所有點擊加載完(對少許數據還行,大量數據的站去死吧) 在Firefox裏面copy出源碼信息 進
行正則匹配

    2.HttpFox抓包  直接抓ajax地址的數據  分析ajax連接 變換參數  取得json後再正則

0x5.正則處理

python對正則表達式的支持模塊。若是http庫有選擇的餘地外,re幾乎是沒有選擇餘地的工具。由於有正則表達式的存在,因此讓咱們能夠很靈活的去摳取抓取過來的完整html中所須要的部分。

固然,這篇文章不會詳細解釋正則表達式,由於若是要系統的介紹正則表達式,或許能夠寫一本書了。這裏只簡單提一下咱們後面會用到的python正則表達式的用法。

re.compile()。若是正則表達式比較多,請一 定要先用這個方法先行編譯正則表達式,以後再正則表達式的使用就會很很是快,由於你們都知道,python文件在第一次運行會分別建立一個字節碼文件,如 果正則表達式做爲字符串的時候,在運行時纔會被編譯,是會影響到python的執行速度的。

compile()返回的是一個re對象,該對象擁有re庫的search(), match(), findall()等方法,這三個方法,在後面會被頻繁的用到,生成被編譯的re對象還有一個好處是調用方法不用再傳入字符串的正則表達式。

search()主要用來校驗正則表達式可否匹配字符串中的一段,一般用來判斷該頁面是否有我須要的內容。



match()用來判斷字符串是否徹底被一個正則表達式匹配,後面用的比較少。



findall()用來搜索正則表達式在字符串中的全部匹配,並返回一個列表,若是沒有任何匹配,則返回一個空列表。



帶有子組的正則表達式,findall()返回的列表中的每一個元素爲一個元組,正則表達式中有幾個子組,元組中就會有幾個元素,第一個元素爲第一個括號中的子組匹配到的元素,以此類推。

findall()和search()是有相似之處的,都是搜索正則表達式在字符串中的匹配,可是findall()返回一個列表,search()返回一個匹配對象,並且findall()返回的列表中有全部匹配,而search()只返回第一個匹配的匹配對象。

0x6.Reference:

python urllib下載網頁
http://www.cnpythoner.com/post/pythonurllib.html

關於不得不在python中使用代理訪問網絡的方法
http://blogread.cn/it/wap/article/1967

python使用urllib2抓取防爬取連接
http://www.the5fire.net/python-urllib2-crawler.html

Python實戰中階(一)——爬取網頁的一點分享
http://blog.goodje.com/2012-08/python-middle-action-web-crawler.html

Python Urllib2使用:代理及其它
http://isilic.iteye.com/blog/1806403

Python urllib2遞歸抓取某個網站下圖片 
http://blog.csdn.net/wklken/article/details/7364899

用Python抓網頁的注意事項
http://blog.raphaelzhang.com/2012/03/issues-in-python-crawler/

urllib.urlretrieve下載圖片速度很慢 + 【已解決】給urllib.urlretrieve添加user-agent
http://www.crifan.com/use_python_urllib-

urlretrieve_download_picture_speed_too_slow_add_user_agent_for_urlretrieve/
相關文章
相關標籤/搜索