Spider

[TOC]

1.基本概念

爬蟲就是獲取網頁並提取和保存信息的自動化程序

1.HTTP基本原理理

1.URI和URL

URI (Uniform Resource Identifier) 統一資源標誌符
URL(Universal Resource Locator) 統一資源定位符

URL是URI的子集, URI還包括一個子類URN (Universal Resource Name) 統一資源名稱,URN 只命名資源不指定如何定位資源。

2.超文本 (hypertext)

網頁源代碼,html代碼 查看源代碼工具和方法

3.HTTP和HTTPS

HTTP (Hyper Text Transfer Protocol) 超文本傳輸協議
HTTPS (Hyper Text Transfer Protocol over Secure Socket Layer)

HTTP加入SSL層,傳輸內容通過SSL加密
安全通道保證數據傳輸安全
確認網站真實性

4.HTTP請求過程

用瀏覽器開發者工具觀察網絡請求過程

1.請求

請求方法 (Request Method)
GET請求的參數直接在URL里,最多隻有1024字節
POST請求數據一般通過表單提交,不會出現在URL里,大小沒有限制

序號 方法 描述
1 GET 請求指定的頁面信息,並返回實體主
2 POST 向指定資源提交數據進行處理請求(例如提交表單或者上傳文件),數據被包含在請求體中。POST請求可能會導致新的資源的建立或已有資源的修改
3 HEAD 類似GET請求,只不過返回的響應中沒有具體內容,用於獲取報頭
4 PUT 從客戶端向服務器傳送數據取代指定的文檔的內容
5 DELETE 請求服務器刪除指定的頁面
6 CONNECT http/1.1協議中預留給能夠講連接改爲管道方式的代理服務器
7 OPTIONS 允許客戶端查看服務器的性能
8 TRACE 回顯服務器收到的請求,主要用於測試或診斷

2.請求頭

Cache-Control

指定了服務器和客戶端在交互時遵循的緩存機制,即是否要留下緩存頁面數據。 一般在使用瀏覽器訪問時,都會在計算機本地留下緩存頁面,相當於是瀏覽器中的頁面保存和 下載選項。但是爬蟲就是爲了從網絡上爬取數據,所以幾乎不會從緩存中讀取數據。所以在設置的時候要側重從服務器請求數據而非加載緩存。

  • no-cache:客戶端告訴服務器,自己不要讀取緩存,要向服務器發起請求
  • no-store:同時也是響應頭的參數,請求和響應都禁止緩存,即不存儲
  • max-age=0:表示當訪問過此網頁後的多少秒內再次訪問,只加載緩存,而不去服務器請求,在爬蟲時一般就寫0秒 .
  • 一般爬蟲就使用以上幾個參數,其他的參數都是接受緩存的,所以就不列出了。
User-Agent

中文名:用戶代理,服務器從此處知道客戶端的操作系統類型和版本,電腦CPU類型,瀏覽器種類版本,瀏覽器渲染引擎,等等。這是爬蟲當中最重要的一個請求頭參數,所以一定要僞造,甚至多個。如果不進行僞造,而直接使用各種爬蟲框架中自定義的user-agent,很容易被封禁。
舉例: User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0 User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36

Accept

指定客戶端可以接受的內容類型,比如文本,圖片,應用等等,內容的先後排序表示客戶端接收的先後次序,每種類型之間用逗號隔開。 其中,對於每一種內容類型,分號 ; 後面會加一個 q=0.6 這樣的 q 值,表示該種類型被客戶端喜歡接受的程度,如果沒有表示 q=1,數值越高,客戶端越喜歡這種類型。 爬蟲的時候,一般會僞造若干,將想要找的文字,圖片放在前面,其他的放在後面,最後一定加上/;q=0.8。
比如Accept: imagegif,imagex-xbitmap,imagejpeg,applicationx-shockwaveflash,applicationvnd.ms-excel,applicationvnd.ms-powerpoint,applicationmsword,

  • textxml,textshtml:文本類型,斜槓後表示文檔的類型,xml,或者shtml
  • applicationxml,applicationxhtml+xml:應⽤用類型,後⾯面表示⽂文檔類型,比如 flash動畫,excel 表格等等
  • imagegif,imagex-xbitmap:圖片類型,表示接收何種類型的圖片
  • /:表示接收任何類型,但是這一條一般寫在最後,表示優先接收前面規定的類型,然後再加載其他類型。
Accept-Language

客戶端可以接受的語言類型,參數值規範和 accept的很像。一般就接收中文和英文,有其他語言需求自行添加。
比如: Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.6,en;q=0.4

  • zh-CN:中文簡體大陸?
  • zh:其他中⽂文
  • en-US:英語美語
  • en:其他英語
Accept-Encoding

客戶端接收編碼類型,一些網絡壓縮格式:
Accept-Encoding: gzip, deflate, sdch。相對來說,deflate是一種過時的壓縮格式,現在常用的是gzip

Accept-Charset

指的是規定好服務器處理表單數據所接受的字符集,也就是說,客戶端瀏覽器告訴服務器自己的表單數據的字符集類型,用以正確接收。若沒有定義,則默認值爲“unknown”。如果服務器沒有包含此種字符集,就無法正確接收。一般情況下,在爬蟲時不定義該屬性,如果定義,例子如下:
Accept-Charset:gb2312,gbk;q=0.7,utf-8;q=0.7,*;q=0.7

Referer

瀏覽器上次訪問的網頁url,uri。由於http協議的無記憶性,服務器可從這裏瞭解到客戶端訪問的前後路徑,並做一些判斷,如果後一次訪問的 url 不能從前一次訪問的頁面上跳轉獲得, 在一定程度上說明了請求頭有可能僞造。

DNT

是 do not track 的縮寫,告訴服務器,瀏覽器客戶端是否禁止第三方網站追蹤。這一條主要是用來保護瀏覽器用戶隱私的,通過此功能,用戶可以檢測到跨站跟蹤、cookie跟蹤等等。 在爬蟲時一般都是禁止的。數字1代表禁止追蹤,0代表接收追蹤,null代表空置,沒有規定。

Connection

請求頭的 header字段指的是當 client 瀏覽器和 server 通信時對於長鏈接如何處理。由於http 請求是無記憶性的,長連接指的是在 client 和server 之間建立一個通道,方便兩者之間進行多次數據傳輸,而不用來回傳輸數據。有 close,keep-alive 等幾種賦值,close表示不想建立長連接在操作完成後關閉鏈接,而keep-alive 表示希望保持暢通來回傳輸數據。 爬蟲時一般都建立一個長鏈接。

Proxy-Connection

當使用代理服務器的時候,這個就指明了代理服務器是否使用長鏈接。但是,數據在從client 到代理服務器,和從代理服務器到被請求的服務器之間如果存在信息差異的話,會造成信息請求不到,但是在大多數情況下,都還是能夠成立的。

Pragma

防止頁面被緩存, 和 cache-control類似的一個字段,一般爬蟲都寫成 no-cache。

Cookie

同樣是一個比較關鍵的字段,Cookie是 client 請求服務器時,服務器會返回一個鍵值對樣的數據給瀏覽器,下一次瀏覽器再訪問這個域名下的網頁時,就需要攜帶這些鍵值對數據在 Cookie中,用來跟蹤瀏覽器用戶的訪問前後路徑。 在爬蟲時,根據前次訪問得到 cookie數據,然後添加到下一次的訪問請求頭中。

Host

訪問的服務器主機名,比如百度的 www.baidu.com。這個值在爬蟲時可以從訪問的 URI 中獲得。

If-Modified-Since

只有當所請求的內容在指定的日期之後又經過修改才返回它,否則返回304。其目的是爲了提高訪問效率。但是在爬蟲時,不設置這個值,而在增量爬取時才設置一個這樣的值,用以更新信息。

Authorization

當客戶端接收到來自WEB服務器的 WWW-Authenticate 響應時,該頭部來回應自己的身份驗證信息給WEB服務器。主要是授權驗證,確定符合服務器的要求。這個在爬蟲時按需而定。

一個典型的適用於爬蟲爬取數據的僞造請求頭如下所示:
“Proxy-Connection”: “keep-alive”,
“Pragma”: “no-cache”,
“Cache-Control”: “no-cache”,
“User-Agent”: “Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36”,
“Accept”:“texthtml,applicationxhtml+xml,applicationxml;q=0.9,imagewebp,/;q=0.8”, “DNT”: “1”,
“Accept-Encoding”: “gzip, deflate, sdch”,
“Accept-Language”: “zh-CN,zh;q=0.8,en-US;q=0.6,en;q=0.4”,
“Referer”: “https://www.baidu.com/s?wd=%BC%96%E7%A0%81&rsv_spt=1&rsv_iqid=0x9fcbc99a0000b5d7&issp=1&f=8&rsv_ bp=1&rsv_idx=2&ie=utf-8&rqlang=cn&tn=baiduhome_pg&rsv_enter=0&oq=If-NoneMatch&inputT=7282&rsv_t=3001MlX2aUzape9perXDW%2FezcxiDTWU4Bt%2FciwbikdOL
QHYY98rhPyD2LDNevDKyLLg2&rsv_pq=c4163a510000b68a&rsv_sug3=24&rsv_sug1=14 &rsv_sug7=100&rsv_sug2=0&rsv_sug4=7283”, “Accept-Charset”: “gb2312,gbk;q=0.7,utf-8;q=0.7,*;q=0.7”,

請求體 (Request Body)

POST請求體有內容,GET請求,請求體爲空
設置Request Header Content-Type

  • application/x-www-form-urlencoded 表單數據
  • multipart/form-data 表單⽂文件上傳
  • application/json 序列列化json數據
  • text/xml xml數據

響應

響應狀態碼 (Response Status Code)

響應頭,其中包含了服務器對請求的應答信息,如 Content-Type、Server、Set-Cookie 等, 下面將一些常用的頭信息說明如下:

  • Date,標識 Response 產生的時間。
  • Last-Modified,指定資源的最後修改時間。
  • Content-Encoding,指定 Response 內容的編碼。
  • Server,包含了了服務器的信息,名稱,版本號等。
  • Content-Type,文檔類型,指定了返回的數據類型是什什麼,如texthtml 則代表返回 HTML 文 檔,applicationx-javascript 則代表返回 JavaScript 文件,image/jpeg 則代表返回了了圖⽚片。
  • Set-Cookie,設置Cookie,Response Headers 中的 Set-Cookie即告訴瀏覽器需要將此內容放在 Cookies 中,下次請求攜帶 Cookies 請求。
  • Expires,指定 Response 的過期時間,使用它可以控制代理服務器或瀏覽器將內容更新到緩存中,如果再次訪問時,直接從緩存中加載,降低服務器負載,縮短加載時間。

響應體 Resposne Body

即響應體,最重要的當屬響應體內容了,響應的正文數據都是在響應體中,如請求一個網頁, 它的響應體就是網頁的HTML 代碼,請求一張圖片,它的響應體就是圖片的二進制數據。所以最主要的數據都包含在響應體中了了,我們做爬蟲請求網頁後要解析的內容就是解析響應體。

網頁的組成

html, css, javascript

網頁結構和節點關係

目標 CSS XPath
所有元素 * //*
所有的P元素 p //p
所有的P元素的子元素 p>* //p/*
根據ID獲取元素 #foo //*[@id='foo']
根據Class獲取元素 .foo //*[contains(@class,'foo')]
擁有某個屬性的元素 *[title] //*[@title]
所有P元素的第一個子元素 p>*:first-child //p/*[0]
所有擁有子元素a的P元素 無法實現 //p[a]
下一個兄弟元素 p+* //p/following-sibling::*[0]
會話和cookie

無狀態http

爬蟲代理

免費、付費

  • 高度匿名代理
    會將數據包原封不動轉發,服務端記錄的是代理服務器的ip
  • 普通匿名代理
    代理服務器通常會加入http頭 HTTP_VIA HTTP_X_FORWARD_FOR,可能能查到客戶端的IP

urllib庫

urllib是基於http的高層庫,它有以下四個主要功能:

  1. request處理理客戶端的請求
  2. response處理理服務端的響應
  3. parse會解析url
  4. 主要用來識別網站的robots.txt⽂文件,用得較少

獲取響應信息

# 獲取網頁內容
import urllib.
request response = urllib.request.urlopen('http://www.baidu.com/') 
html = response.read().decode("utf-8") print(html)

# 取響應狀態碼和頭信息 
print(response.status) 
print(response.getheaders()) 
print(response.getheader("Server"))

設置超時時間

import urllib.
request response = urllib.request.urlopen("http://2018.sina.com.cn/", timeout=1) html = response.read().decode("utf-8") 
print(html)

設置請求頭和參數

from urllib import request, parse
url = "http://2018.sina.com.cn/" 
headers = {  "User-Agent": "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; 360SE)",  "Host": "2018.sina.com.cn", } 
dict = {  "name": "Question" } data = bytes(parse.urlencode(dict), encoding="utf8") req = request.Request(url=url, data=data, headers=headers, method="GET") response = request.urlopen(req) 
print(response.read().decode("utf-8"))

異常處理

from urllib import request, error
try:  
  response = request.urlopen("https://cuiqingcai.com/index.htm") 
except error.URLError as e:  
  print(e.reason)

用爬蟲下載圖片
pip install request

import requests
r = requests.get("http://www.baidu.com") 
print(r.status_code) 
print(r.text) 
print(r.cookies)

解析庫的使用

XPath

XML Path Language XML 路路徑語⾔言

安裝lxml庫 (支持HTML和XML解析,支持XPath解析方式)
pip3 install lxml

Beautiful Soup

pip3 install beautifulsoup4

解析器
  • Python 標準庫 BeautifulSoup(html, “html.parser”) 速度一般,容錯能力好
  • lxml HTML解析器 BeautifulSoup(html, “lxml”) 速度快,容錯好
  • lxml xml解析器 BeautifulSoup(markup, “xml”) 速度快,唯一支持xml
  • html5lib BeautifulSoup(markup, “html5lib”) 容錯性高,速度慢

引入BeautifulSoup

from bs4 import BeautifulSoup

獲取方法

soup = BeautifulSoup(html, "lxml") # 試⽤用lxml解析器器構造beautifulsoup print(soup.prettify())  # 取⽹網⻚頁縮進格式化輸出 
print(soup.title.string) # 取⽹網⻚頁title內容 
print(soup.head) 
print(soup.p)

# 獲取節點的名字 
print(soup.title.name) 
# 獲取節點屬性 
soup.img.attrs["src"]
print(soup.p.attrs) 
print(soup.p.attrs["name"]) 
print(soup.p["class"]) 
# 獲取節點包含的內容 
print(soup.p.string)

嵌套選擇
<head>
<title>this is title</title>
</head>

# soup的節點都爲 bs4.element.Tag類型,可以繼續選擇 
print(soup.head.title.string)

關聯選擇
有些元素沒有特徵定位,可以先選擇有辦法定位的,然後以這個節點爲準選擇它的子節點、父 節點、兄弟節點等
<p class="p1"></p>
<p></p>
<p></p>

print(soup.p.contents) # 取p節點下面所有⼦節點列表 
print(soup.p.descendants) #取p節點所有子孫節點 
print(soup.a.parent) # 取父節點 
print(soup.a.parents) # 取所有祖先節點 
print(soup.a.next_sibling) # 同級下一節點 
print(soup.a.previous_sibling) # 同級上一節點 
print(soup.a.next_siblings) # 同級所有後面節點 
print(soup.a.previous_siblings) # 同級所有前面節點 
print(list(soup.a.parents)[0].attrs['class'])

方法選擇器
根據屬性和文本進行查找
<ul><li><li><ul>
<ul><li><li>jjj<li><li></ul>

print(soup.find_all(name="ul"))
for ul in soup.find_all(name="ul"):  
  print(ul.find_all(name="li"))  
  for li in ul.find_all(name="li"):    
    print(li.string)
soup.find_all(attrs={"id": "list-1"})

css 選擇器器
<p id="p1" class="panel"><p class=""><p><p>

soup.select('.panel .panel_heading') 
soup.select('ul li') 
soup.select('#id1 .element')

使用Selenium爬取動態渲染頁面

模擬瀏覽器操作爬取頁面

安裝Selenium
pip3 install selenium

安裝ChromeDriver
ChromeDriver與Chrome對照表
ChromeDriver v2.41 (2018-07-27)—————Supports Chrome v67-69 ChromeDriver v2.40 (2018-06-07)----------Supports Chrome v66-68
ChromeDriver v2.39 (2018-05-30)----------Supports Chrome v66-68
ChromeDriver v2.38 (2018-04-17)----------Supports Chrome v65-67
ChromeDriver v2.37 (2018-03-16)----------Supports Chrome v64-66
ChromeDriver v2.36 (2018-03-02)----------Supports Chrome v63-65

將chromdriver.exe 文件放到Python Scripts目錄下或配置PATH路徑命令行執行chromedriver

from selenium import webdriver 
brower = webdriver.Chrome()

selenium.webdriver.common.by.By
CLASS_NAME = 'class name'
CSS_SELECTOR = 'css selector'
ID = 'id' LINK_TEXT = 'link text'
NAME = 'name'
PARTIAL_LINK_TEXT = 'partial link text'
TAG_NAME = 'tag name'
XPATH = 'xpath'

驗證碼識別

圖形驗證碼


tesseerocr
tesseract a.jpg result -l eng && cat result.txt
識別率低

識別驗證碼平臺(打碼平臺)
超級鷹

驗證碼類型與價格表-超級鷹驗證碼識別

極驗滑動驗證碼

step1. 模擬點擊驗證按鈕
step2. 識別滑動缺⼝口位置 遍歷沒有缺⼝口和有缺⼝口的兩張圖⽚片,找出相同位置像素差距超過指定值的像素點,即缺⼝口位置 (⽬目前極驗已經改進了了算法)
step3. 模擬拖動滑塊



代理

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