爬取資料
這一步,你要明確要得到的內容是什麼?是HTML原始碼,還是Json格式的字串等。
1. 最基本的爬取
抓取大多數情況屬於get請求,即直接從對方伺服器上獲取資料。
首先,Python中自帶urllib及urllib2這兩個模組,基本上能滿足一般的頁面抓取。另外,requests也是非常有用的包,與此類似的,還有httplib2等等。
import requests url = current.ip.16yun.cn:802 response = requests.get(url) content = requests.get(url).content print(“response headers:”, response.headers) print(“content:”, content)
此外,對於帶有查詢欄位的url,get請求一般會將來請求的資料附在url之後,以?分割url和傳輸資料,多個引數用&連線。
import requests data = {‘wd’:’nike’, ‘ie’:’utf-8’} url=’https://www.baidu.com' response = requests.get(url=url, params=data)
2. 對於登陸情況的處理
2.1 使用表單登陸
這種情況屬於post請求,即先向伺服器傳送表單資料,伺服器再將返回的cookie存入本地。
import requests data = {‘data1’:’XXXXX’, ‘data2’:’XXXXX’} response = requests.post(url=url, data=data)
2.2 使用cookie登陸
使用cookie登陸,伺服器會認為你是一個已登陸的使用者,所以就會返回給你一個已登陸的內容。因此,需要驗證碼的情況可以使用帶驗證碼登陸的cookie解決。
#! -- encoding:utf-8 -- import requests import random import requests.adapters # 要訪問的目標頁面 targetUrlList = [ “https://httpbin.org/ip", “https://httpbin.org/headers", “https://httpbin.org/user-agent", ] # 代理伺服器(產品官網 www.16yun.cn) proxyHost = “t.16yun.cn” proxyPort = “31111” # 代理隧道驗證資訊 proxyUser = “username” proxyPass = “password” proxyMeta = “http://%(user)s:%(pass)s@%(host)s:%(port)s” % { “host”: proxyHost, “port”: proxyPort, “user”: proxyUser, “pass”: proxyPass, } # 設定 http和https訪問都是用HTTP代理 proxies = { “http”: proxyMeta, “https”: proxyMeta, } # 訪問三次網站,使用相同的Session(keep-alive),均能夠保持相同的外網IP s = requests.session() # 設定cookie cookie_dict = {“JSESSION”:”123456789”} cookies = requests.utils.cookiejar_from_dict(cookie_dict, cookiejar=None, overwrite=True) s.cookies = cookies for i in range(3): for url in targetUrlList: r = s.get(url, proxies=proxies) print r.text
若存在驗證碼,此時採用response = requests_session.post(url=url_login, data=data)是不行的,做法應該如下:
response_captcha = requests_session.get(url=url_login, cookies=cookies) response1 = requests.get(url_login) # 未登陸 response2 = requests_session.get(url_login) # 已登陸,因為之前拿到了Response Cookie! response3 = requests_session.get(url_results) # 已登陸,因為之前拿到了Response Cookie!
3. 對於反爬蟲機制的處理
3.1 使用代理
適用情況:大部分網站均限制了IP的訪問量
對於“頻繁點選”的情況,我們還可以通過限制爬蟲訪問網站的頻率來避免被網站禁掉。
#! -- encoding:utf-8 -- import requests import random # 要訪問的目標頁面 targetUrl = “http://httpbin.org/ip" # 要訪問的目標HTTPS頁面 # targetUrl = “https://httpbin.org/ip" # 代理伺服器(產品官網 www.16yun.cn) proxyHost = “t.16yun.cn” proxyPort = “31111” # 代理隧道驗證資訊 proxyUser = “username” proxyPass = “password” proxyMeta = “http://%(user)s:%(pass)s@%(host)s:%(port)s” % { “host” : proxyHost, “port” : proxyPort, “user” : proxyUser, “pass” : proxyPass, } # 設定 http和https訪問都是用HTTP代理 proxies = { “http” : proxyMeta, “https” : proxyMeta, } # 設定IP切換頭 tunnel = random.randint(1,10000) headers = {“Proxy-Tunnel”: str(tunnel)} resp = requests.get(targetUrl, proxies=proxies, headers=headers) print resp.status_code print resp.text
3.2 時間設定
適用情況:限制頻率情況。大部分網站有頻率限制,比如搜尋後需要一定間隔才能獲取詳情頁面等。
我們可以用sleep方式來做出以下延遲。
import time time.sleep(1)
3.3 偽裝成瀏覽器,或者反“反盜鏈”
有些網站會檢查你是不是真的瀏覽器訪問,還是機器自動訪問的。這種情況,加上User-Agent,表明你是瀏覽器訪問即可。有時還會檢查是否帶Referer資訊還會檢查你的Referer是否合法,一般再加上Referer。
User-Agent可以用億牛雲提供給的真實庫,Referer的來源可以偽裝成百度搜尋來的。
headers = {‘User-Agent’:’Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.1276.73 Safari/537.36’, ‘Referer’:’https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd=nike'} response = requests.get(url=url, headers=headers)
4. 對於Ajax請求的處理
對於“載入更多”情況,使用Ajax來傳輸很多資料。
它的工作原理是:從網頁的url載入網頁的原始碼之後,會在瀏覽器裡執行JavaScript程式。這些程式會載入更多的內容,“填充”到網頁裡。這就是為什麼如果你直接去爬網頁本身的url,你會找不到頁面的實際內容。
這裡,若使用Google Chrome分析”請求“對應的連結(方法:右鍵→審查元素→Network→清空,點選”載入更多“,出現對應的GET連結尋找Type為text/html的,點選,檢視get引數或者複製Request URL),迴圈過程。
如果“請求”之前有頁面,依據上一步的網址進行分析推導第1頁。以此類推,抓取抓Ajax地址的資料。
對返回的json格式資料(str)進行正則匹配。json格式資料中,需從’\uxxxx’形式的unicode_escape編碼轉換成u’\uxxxx’的unicode編碼。
爬取有兩個需要注意的問題:
如何處理js生成的cookie
如何控制頻率和利用代理破除反爬限制
本作品採用《CC 協議》,轉載必須註明作者和本文連結