1. 程式人生 > >關於反爬蟲的一些總結

關於反爬蟲的一些總結

1、爬取過程中的302重定向

在爬取某個網站速度過快或者發出的請求過多的時候,網站會向你所在的客戶端傳送一個連結,需要你去驗證圖片。我在爬鏈家和拉鉤網的過程中就曾經遇到過:

image.png

對於302重定向的問題,是由於抓取速度過快引起網路流量異常,伺服器識別出是機器傳送的請求,於是將請求返回連結定到某一特定連結,大多是驗證圖片或空連結。

在這種時候,既然已經被識別出來了,就使用代理ip再繼續抓取。

2、headers標頭檔案

有些網站對爬蟲反感,對爬蟲請求一律拒絕,這時候我們需要偽裝成瀏覽器,通過修改http中的headers來實現

headers = {
'Host': "bj.lianjia.com"
,
'Accept': "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
'Accept-Encoding': "gzip, deflate, sdch",
'Accept-Language': "zh-CN,zh;q=0.8",
'User-Agent': "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.87 Safari/537.36",
'Connection': "keep-alive"
,
}
p = requests.get(url, headers=headers)
print(p.content.decode('utf-8'))

3、模擬登陸

一般登入的過程都伴隨有驗證碼,這裡我們通過selenium自己構造post資料進行提交,將返回驗證碼圖片的連結地址輸出到控制檯下,點選圖片連結識別驗證碼,輸入驗證碼並提交,完成登入。

from selenium import webdriver
from selenium.webdriver.common.keys import Keys #
from selenium.webdriver.support.ui import WebDriverWait
# WebDriverWait的作用是等待某個條件的滿足之後再往後執行
from selenium.webdriver import ActionChains
import time
import sys
driver = webdriver.PhantomJS(executable_path='C:\PyCharm 2016.2.3\phantomjs\phantomjs.exe') # 構造網頁驅動

driver.get('https://www.zhihu.com/#signin') # 開啟網頁
driver.find_element_by_xpath('//input[@name="password"]').send_keys('your_password')
driver.find_element_by_xpath('//input[@name="account"]').send_keys('your_account')
driver.get_screenshot_as_file('zhihu.jpg') # 擷取當前頁面的圖片
input_solution = input('請輸入驗證碼 :')
driver.find_element_by_xpath('//input[@name="captcha"]').send_keys(input_solution)
time.sleep(2)

driver.find_element_by_xpath('//form[@class="zu-side-login-box"]').submit() # 表單的提交 表單的提交,即可以選擇登入按鈕然後使用click方法,也可以選擇表單然後使用submit方法
sreach_widonw = driver.current_window_handle # 用來定位當前頁面
# driver.find_element_by_xpath('//button[@class="sign-button submit"]').click()
try:
dr = WebDriverWait(driver,5)
# dr.until(lambda the_driver: the_driver.find_element_by_xpath('//a[@class="zu-side-login-box"]').is_displayed())
if driver.find_element_by_xpath('//*[@id="zh-top-link-home"]'):
print('登入成功')
except:
print('登入失敗')
driver.save_screenshot('screen_shoot.jpg') #擷取當前頁面的圖片
sys.exit(0)
driver.quit() #退出驅動

這裡面,PhantomJS是一個很棒的exe,下載地址:phantomjs。他可以模擬瀏覽器行為進行操作。當我們遇到JS渲染的網頁,在使用正則表示式、BS4和xpath . . . 都無法匹配出資料時(資料根本沒載入上),可以使用PhantomJS模擬瀏覽器行為傳送請求,將會得到網頁的原始全部資料。

4、代理ip

當爬取速度過快時,當請求次數過多時都面臨ip被封的可能。因此使用代理也是必備的。

使用request加代理

import requests
proxies = { "http": "http://10.10.1.10:3128",
"https": "http://10.10.1.10:1080",}
p = request.get("http://www.baidu.com", proxies = proxies)
print(p.content.decode('utf-8'))

使用urllib加代理

user_agent ='Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.22 Safari/537.36 SE 2.X MetaSr 1.0'
headers = {'User-Agent':user_agent}
proxy = {'http':'http://10.10.1.10:1080',}
proxy_handler = urllib.request.ProxyHandler(proxy)
opener = urllib.request.build_opener(proxy_handler)
urllib.request.install_opener(opener)
url = "https://www.baidu.com/"
req = urllib.request.Request(url=url,headers=headers)
res = urllib.request.urlopen(req)
print(res.read().decode('utf-8')) # 列印網頁內容

5、驗證碼輸入

遇到驗證的問題,我一般都是人工識別:獲取驗證碼的連結再控制檯下 ——> 點選連結識別驗證碼 ——> 在控制檯手動輸入驗證碼並提交。

6、ajax載入的資料

對於ajax載入的資料,我們無論通過request或post方法請求得到的網頁都無法得到。

關於一個網頁是否是ajax載入資料,我們只需將網頁內容print到控制檯下,將其與網頁原始內容進行比對,如果有資料缺失,那麼這些資料就是ajax載入。例如:我們想獲取京東上商品的價格、銷量、好評等方面的資料,但是請求返回的網頁中沒有這些資料。因為這些資料是ajax載入。對於ajax載入的頁面,一般有兩種方法。

(1)分析網頁

按F12開啟瀏覽器除錯工具,在Network下選擇XHR或Doc標籤,分析(雙擊點開檢視)這兩個標籤下的連結。如果點開連結開啟的網頁中正好有那些沒有載入的資料,則這些資料是通過該連結傳送的。再對該連結進行規律分析,以後對該連結傳送請求。

image.png

(2)使用PhantomJS模擬瀏覽器行為

使用PhantomJS模擬瀏覽器進行傳送請求,得到返回的內容是完全的(ajax載入的資料也會有)。但是使用PhantomJS請求速度過慢,一般一個網頁4~5s時間,不能忍。一般要使用PhantomJS需要開多執行緒。

driver = webdriver.PhantomJS(executable_path='C:\PyCharm 2016.2.3\phantomjs\phantomjs.exe')  # 構造網頁驅動

driver.get('https://www.zhihu.com/')
print(driver.page_source) # 列印網頁內容