Python分佈式爬蟲(三) - 爬蟲基礎知識

0 相關源碼

1 技術選型 爬蟲能作什麼

1.1 scrapy VS requests + beautifulsoup

作爬蟲的時候,常常都會聽到 scrapy VS requests+beautifulsoup的組合 在本次分佈式爬蟲實現中只用scrapy而不用後者的緣由是:css

  • requests 和 beautifulsoup 都是庫, scrapy是一個框架 框架中能夠應用 requests等,能夠集合不少第三方庫html

  • 基於 twisted(異步IO框架) 性能是最大的優點web

  • 方便擴展 提供了不少內置的功能,提升開發速度ajax

  • 內置 css和 xpath selector 對html或者xml進行分析,很是方便, beautifulsoup缺點就是慢正則表達式

實踐中仍是會用到requests,可是不會用到beautifulsoup,由於它的功能能夠直接使用scrapy的select完成.數據庫

1.2 網頁分類

常見類型的服務

  • 靜態網頁 事先在服務器端生成好的頁面,內容固定緩存

  • 動態網頁 從服務器端取數據返回bash

  • webservice(REST API) 也是屬於動態網頁的一種,只是經過ajax方式和後臺交互的一種技術服務器

1.3 爬蟲能作什麼

  • 搜索引擎-百度,google,垂直領域搜索引擎(有一個目標,知道本身到底爬什麼數據)網絡

  • 推薦引擎-今日頭條(根據瀏覽習慣猜想感興趣的內容進行推送)

  • 機器學習的數據樣本

  • 數據分析-金融數據分析,輿情分析

2 正則表達式

2.1 爲什麼須要

爲何有css或者xpath selector還要學正則表達式,有時候根據selector得到了整個標籤內的內容,可是還要進行進一步的篩選,好比裏面的數字信息等

2.2 做用

能夠幫咱們判斷某個字符串是否符合某一個模式 提取整個字符串裏面的重要的部分信息

2.3 經常使用字符的用法

^ : 以什麼字符開頭$ : 以什麼字符結尾. : 任意字符* :出現任意次數,0次或者更屢次():還提取按模式取出來的子串。例如,".*(b.\*b).\*"表示無論先後是什麼的兩個b之間的子串? :下面詳解+ :字符至少出現一次{1}:前面的字符出現一次{3,}: 要求前面的字符必須出現3次以上{2,5}:前面的字符至少出現2次,最少出現5次| : 或的關係\[\] : 中括號裏面的內容只要知足任何一個便可,也能夠是一個區間,中括號裏面的^表示不等於,中括號裏面的符號就是符號,不是特殊符號的含義\\s :表示空格符\\S : 恰好與小s的意思相反,只要不是空格均可以\\w : 表示\[A-Za-z0-9_\]其中的任意一個字符\\W : 與\\w的意思恰好相反\[\\u4E00-\\u9FA5\] : unicode編碼,含義是漢字,意思是隻要出現漢字就能夠。\\d : 表示數字
複製代碼

2.4 coding 演示

新建項目
複製代碼

^ : 以什麼字符開頭 此處以J開頭便可!
複製代碼

$ : 以什麼字符結尾 此處以4結尾便可!
複製代碼

J開頭,中間爲任意字符,最後以4結尾
複製代碼

? : 非貪婪匹配模式

默認的狀況下,匹配是貪婪模式,匹配最大長度 好比對於 "bobby123"這個待匹配的,結果就是bb,而不是bobb,因此這就是貪婪,反向匹配(或者理解成直到結束符合的最後一個結果) 非貪婪匹配就是從左邊開始,只須要出現一個結果就能夠了,".?(b.?b)."表示對兩個b從左到右只要出現一次就可 ".?(b.b)."第二個b不要問好,那麼第二個b就是貪婪模式,會持續匹配到最後一個b

  • 如今源數據變動爲 

  • 欲取得字符串 boooooooob 

  • 然而現實,倒是 

非貪婪模式儘量少的匹配所搜索的字符串,而默認的貪婪模式則儘量多的匹配所搜索的字符串。例如,對於字符串「oooo」,「o+?」將匹配單個「o」,而「o+」將匹配全部「o」。

此處貪婪匹配最開始時反向匹配,從右向左,因此獲得bb結果串!就沒法提取目標串!何解?

那就須要咱們的 `?`了!變成一種非貪婪模式
複製代碼

因而咱們,更改匹配規則
複製代碼

結果使人失望!竟然還多了個小b!!!![](https://mmbiz.qpic.cn/mmbiz_png/PlhAddctCRXMWLbhBpkaUrP89DN8tKGCOMXf987rIvs54icvONnm2PlOWvurW4hq29DqLGnpQWKVra4ElXFFHXQ/640?wx_fmt=png)雖然左部分正常匹配左邊的b了,可是規則的右部分依舊貪婪匹配!必須讓規則右邊的b不要那麼貪婪!給他也加個 `?`修飾~便可!
複製代碼

終於......提取成功啦!
複製代碼

限定出現次數

| : 表示或關係

  • 下面更改源字符串 

  • 規則 

  • 結果 

  • 想要提取完整的怎麼作呢? 

  • 結果 

[]

規則
複製代碼

結果
複製代碼

  • 匹配電話號碼

規則
複製代碼

其中有 `^`
複製代碼

\s

  • \S只能匹配一個非空字符!!! 

\w

w不知足的空格,W知足!

漢字編碼

  • 源字符串 

  • 想提取究竟是什麼大學 

  • 這樣也是不行的,又產生了貪婪匹配問題 

  • 因此要加上 ?取消貪婪 

完美提取XX大學

d D

  • 源字符串 

  • 想提取1997

  • 這樣是不夠的,只能提取出7 

  • 這樣就ok啦! 

  • 或者必須取消貪婪 

綜合實戰

  • 源字符串 

  • 可提取1,2,3,4 

  • 如下爲完美解決規則 

3 深度優先和廣度優先原理

爬蟲的基本原理,一個網站的url設計是分層的,樹形結構,可以讓咱們爬取網站的時候更加有策略。 在設計網站url時候是不會有環路的,可是在真實網站url連接的結構中,是有環路的。 好比,從首頁到達某個頁面,這個頁面上會有返回首頁的連接。若是一直進入這個死循環,那麼其餘頁面就爬取不到內容了。因此須要用到網頁的去重。 伯樂在線網站的文章爬取其中獲取到的文章url是不會重複的,就不須要去重。但大多數文章都須要去重。

  • 樹形結構的URL設計 

scrapy默認使用深度優先實現的,深度優先使用遞歸實現的,廣度優先是採用隊列來實現的

  • 深度優先 

  • 廣度優先 

4 爬蟲去重策略

  • 將訪問過的url保存到數據庫中 獲取url時查詢一下是否爬過了.雖然數據庫中有緩存,可是每次都查詢效率很低.

  • 將url保存到set中 只須要O(1)的代價就能夠查詢到url,可是內存佔用會愈來愈大 假設有1億條url,那麼就須要1億 x 2byte x 50字符/1024/1024/1024=8G

  • url通過 md5等方法後保存到set中 將url壓縮到固定長度並且不重複, scrapy實際上就是應用這種方法

  • 用bitmap方法 將訪問過的url經過hash函數映射到某一位,對內存壓縮更大,缺點是衝突比較高

  • bloomfilter方法對bitmap進行改進 多重hash函數下降衝突可能性。即減小內存,又減小衝突。

5 字符串編碼

字符串編碼,寫文件以及網絡傳輸過程當中,調用某些函數,常常碰到提示編碼錯誤.

計算機只能處理數字,文本轉換爲數字才能處理. 計算機中8個bit做爲一個字節,因此一個字節能表示最大的數字就是255
複製代碼
計算機是美國人發明的 一個字節能夠表示全部字符了,因此ASCII(一個字節)編碼就成爲美國人的標準編碼
複製代碼
可是ASCII處理中文明顯是不夠的 中文不止255個漢字,因此中國製定了 `GB2312`編碼,用兩個字節表示一個漢字. GB2312還把ASCII包含進去了,同理,日文,韓文等等上百個國家爲了解決這個問題就都發展了一套字節的編碼,標準就愈來愈多,若是出現多種語言混合顯示就必定會出現亂碼.
複製代碼
因而 `unicode`出現了,將全部語言統一到一套編碼裏
複製代碼

看一下ASCII和unicode編碼:

字母A用ASCII編碼十進制是65,二進制 0100 0001
複製代碼
漢字"中" 已近超出ASCII編碼的範圍,用unicode編碼是20013二進制是01001110 00101101
複製代碼
A用unicode編碼只須要前面補0二進制是 00000000 0100 0001
複製代碼
亂碼問題解決了,可是若是內容全是英文,unicode編碼比ASCII編碼須要多一倍的存儲空間,傳輸也會變慢
複製代碼
因此此時出現了可變長的編碼utf-8 把英文:1字節,漢字3字節,特別生僻的變成4-6字節,若是傳輸大量的英文,utf8做用就很明顯。Unicode編碼雖然佔用空間可是由於佔用空間大小等額,在內存中處理會簡單一些。
複製代碼
關於Mac(Linux同理)下編碼格式問題
複製代碼

如下爲 Python2 操做環境!!!

py字符串在內存中全是用Unicode進行編碼的
複製代碼
在Mac下實際上默認是utf8編碼
複製代碼

在調用encode以前,必須把前面的變量轉化爲Unicode編碼.
複製代碼

本來是utf8編碼的不能直接編碼成utf8,由於Python中使用encode方法,前面的變量必須都是Unicode編碼的
複製代碼

因此每次執行encode前必須先decode成Unicode編碼![](https://mmbiz.qpic.cn/mmbiz_png/PlhAddctCRXMWLbhBpkaUrP89DN8tKGC8IazYJPdO0FoB7SJlTKbYJqw9DJD4N5DF5vicwKymqPdiaUGqwfJz9ibA/640?wx_fmt=png)
複製代碼
正由於Python2存在編解碼問題,因此老項目都須要一個文件頭
複製代碼

Python3則不存在此問題,內部所有使用Unicode編碼!!!

如下爲 Python3 操做環境!!!

參考

正則表達

相關文章
相關標籤/搜索