爬蟲打破封禁的幾種方法

寫在前面的話:爬蟲有風險,使用需謹慎(應當遵守行業道德及職業操守,遵守國家法律法規。以下內容均是在此前提下進行操作)
反爬技術基本有:
模擬登陸,模擬瀏覽器,代理服務器......文章在持續更新總結梳理中......
1.代理服務器的設置
目的:防止自有IP地址被屏蔽
推薦免費的代理服務器列表:

http://www.xicidaili.com/

 建立自定義函數,利用代理服務器爬取網頁內容

#代理服務器設置
import urllib.request
def use_proxy(url,proxy_addr): #定義一個具有代理服務器功能的函數
    proxy=urllib.request.ProxyHandler({"http":proxy_addr})
    opener=urllib.request.build_opener(proxy,urllib.request.HTTPHandler) #添加代理IP
    urllib.request.install_opener(opener)  #安裝opener爲全局變量
    data=urllib.request.urlopen(url).read().decode("utf-8","ignore") 
    #用"ignore"忽略編碼錯誤問題
    return data 
    
proxy_addr="106.56.102.102:808"    #有部分代理服務器可能沒有效果,此時應該更換
url="http://xxxxx.com"
data=use_proxy(url,proxy_addr)  #調用use_proxy()函數,傳入實參proxy_addr and url
print(len(data))  #返回獲取內容的大小

2. 模擬登陸問題(自動模擬HTTP請求)
http請求有多種類型,常用get(get請求通過URL網址傳遞信息)和post
查詢時常用到get請求.
比如:

下面是模擬get請求思路:
1.構建對應的URL地址
2.以對應的URL爲參數,構建Request對象
3.通過urlopen()打開構建的Request對象
4.後續操作
具體代碼實現如下:

import urllib.request
keyword="90後"
keyword=urllib.request.quote(keyword) #需要對中文關鍵字進行編碼處理
url="http://www.baidu.com/?wd="+keyword
#https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=0&rsv_idx=1&tn=02049043_8_pg&wd=python&rsv_pq=bfc660810002b9aa&rsv_t=7649UHhrgN4vYkpzTfzJxRWBTXhIXWYnuS3WPgvk4CZWpTAVC0UQYI9ATIQNTK3j2e%2Bsyg&rqlang=cn&rsv_enter=1&rsv_sug3=7&rsv_sug1=7&rsv_sug7=101&rsv_sug2=0&inputT=3503&rsv_sug4=4273
req=urllib.request.Request(url) #網址以請求方式獲取(封裝爲一個請求)
data=urllib.request.urlopen(req).read()
fh=open("D:\xxx.txt",'wb')  #以二進制寫入的方式打開
fh.write(data)
fh.close()

在註冊或者登陸時常用到post請求:
(登陸需要的cookie知識點在此省略)
post請求思路如下:
1.構建好URL網址
2.構建表單數據(urllib.parse.urlencode對數據編碼)
3.創建Request對象(參數應包含URL地址和傳遞的數據)
4.用add_header()添加頭信息,模擬瀏覽器進行爬取
5.使用urllib.request.urlopen()打開對應的Request對象,完成信息的傳遞
6.後續操作
具體代碼實現如下:

import urllib.request
import urllib.parse
url="網址"   #備註:網址應是http形式,因爲urllib不支持HTTPS協議
postdata=urllib.parse.urlencode({
"name":"qingfengxiyu.com",
"pass":"密碼lalala"
}).encode("utf-8") #對數據進行編碼處理
req=urllib.request.Request(url,postdata)
req.add_header('User-Agent','Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0')
data=urllib.request.urlopen(req).read()
fh=open("D:/..../90hou.html","wb")  #以二進制方式創建並打開文件
fh.write(data)
fh.close()  #有開必有關,否則編譯會出錯

爲了增強代碼的健壯性,可有時也可進行超時設置(可根據網頁的服務器反應速度來設置),尤其適合大型項目時,設置好恰當的時間可以提高效率
用timeout來表示

file=urllib.request.urlopen("網址",timeout=10)
#設置10秒反應時間,超時則報錯
案例:
for i in range(0,100):
    try:
        file=urllib.request.urlopen("網址",timeout=10)
        data=file.read()
        print(len(data))
    except Exception as e:
        print("出現異常:"+str(e)) #輸出異常的內容
異常處理增強了程序的健壯性

 爬蟲的異常處理:
未來防止程序遇到異常時,停止或者崩潰,一般用異常處理來增強程序的健壯性
常見狀態碼:
200:運行正常    301: 重新定向到新的URL  403: 禁止訪問  
異常處理的兩種方式:urlError與HTTPError(其中後者是前者的子類)由於HTTPError有異常狀態碼與異常原因,urlerror沒有異常狀態碼,所以不能用urlerror直接代替httperror,如要代替,必須判斷是否有狀態碼屬性.
urlerror產生原因:
1.連接不上
2.遠程的URL不存在
3.本地沒有網絡
4.假若觸發了httperror子類

import urllib.error
import urllib.request
try:
    urllib.request.urlopen("http://blog.csdn.net")
except urllib.error.URLError as e:
    if hasattr(e,"code"):
        print(e.code)
    if hasattr(e,"reason"):
        print(e.reason)
#判斷是否有狀態碼產生

 瀏覽器僞裝技術:
防屏蔽,把爬蟲爬取頁面內容,僞裝成是以瀏覽器的方式進行
簡單僞裝技術(user-Agent)

#簡單僞裝技術
import urllib.request
url="......"
headers=("user-Agent","......")
opener=urllib.request.build_opener()  #創建opener對象,urlopen默認不支持高級報頭,所以做此設置opener.addheader=[headers]       #添加報頭信息
data=opener.open(url).read()  
fh=("D:......","wb")  #以二進制形式寫入文件
fh.write(data)
fh.close()

高仿真僞裝技術(文章更新總結梳理中): 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章