爬蟲總結

一.requests模塊重點梳理

(1)robots協議是什麼?

Robots協議(也稱爲爬蟲協議、爬蟲規則、機器人協議等)也就是robots.txt,網站經過robots協議告訴搜索引擎哪些頁面能夠抓取,哪些頁面不能抓取。python

Robots協議是網站國際互聯網界通行的道德規範,其目的是保護網站數據和敏感信息、確保用戶我的信息和隱私不被侵犯。因其不是命令,故須要搜索引擎自覺遵照。web

(2)列舉您使用過的python網絡爬蟲所用到的網絡數據包

requests, urllib面試

(3)http、https協議有什麼區別?

http協議是超文本傳輸協議,被用於在web瀏覽器和網站服務器之間傳遞信息。http協議工做是以明文方式發送內容,不提供任何形式的數據加密,而這也是很容易被黑客利用的地方,若是黑客截取了web瀏覽器和網站服務器之間的傳輸信息,就能夠直接讀懂其中的信息,所以http協議不適合傳輸一些重要的、敏感的信息,好比信用卡密碼及支付驗證碼等。ajax

安全套接字層https協議就是爲了解決http協議的這一安全缺陷而出生的,爲了數據傳輸的安全,https在http的基礎上加入了ssl協議,ssl依靠證書來驗證服務器的身份,爲瀏覽器和服務器之間的通訊加密,這樣的話即便黑客截取了發送過程當中的信息,也沒法破解讀懂它,咱們網站及用戶的信息便獲得了最大的安全保障。redis

(4)你寫爬蟲的時候都遇到過什麼反爬蟲措施,你是怎麼解決的?

  • 經過headers反爬蟲;數據庫

  • 基於用戶行爲的發爬蟲:同一IP短期內訪問的頻率;json

  • 動態網頁反爬蟲(經過ajax請求數據,或者經過JavaScript生成);瀏覽器

  • 驗證碼安全

  • 數據加密

解決途徑:

  • 對於基本網頁的抓取能夠自定義headers,將header隨request一塊兒發送(通常是User-Agent,Cookie)

  • 使用IP代理池爬取或者下降抓取頻率

  • 使用selenium + phantomjs 進行抓取抓取動態數據,或者找到動態數據加載的json頁面

  • 使用打碼平臺識別驗證碼

  • 對部分數據進行加密的,可使用selenium進行截圖,使用python自帶的pytesseract庫進行識別,可是比較慢最直接的方法是找到加密的方法進行逆向推理。

(5)POST與GET的區別

  • GET數據傳輸安全性低,POST傳輸數據安全性高,由於參數不會被保存在瀏覽器歷史或web服務器日誌中;

  • 在作數據查詢時,建議用GET方式;而在作數據添加、修改或刪除時,建議用POST方式;

  • GET在url中傳遞數據,數據信息放在請求頭中;而POST請求信息放在請求體中進行傳遞數據;

  • GET傳輸數據的數據量較小,只能在請求頭中發送數據,而POST傳輸數據信息比較大,通常不受限制;

  • 在執行效率來講,GET比POST好

(6)爲何會用到代理?

網站的反爬蟲策略會檢測到同一個IP訪問次數頻率過快,從而禁止該IP的訪問。所以爬蟲過程當中須要IP代理避免該問題。

二. 數據解析重點梳理

(1)使用正則對頁面源碼數據進行解析時,應該使用re.S仍是Re.M?

re.S爲單行解析,解析的源碼數據中能夠有換行符,re.S會做用到整個被視爲一個大字符串的頁面源碼數據中。re.M爲多行解析,會將正則做用到源碼的每一行中。在實戰中使用的是re.S。

(2)xpath插件的做用?

能夠在瀏覽器中直接校驗xpath表達式,校驗成功後再將xpath做用到程序中。

(3)xpath表達式回顧

//div[@class=‘xxx’]         # 屬性定位

//div[@id=’xxx’]/a[2]/span  # 層級索引定位

//a[@href=’’and @class=’xxx’]   # 邏輯運算

//div[contains(@class,’xx’)]    # 模糊匹配

//div[starts-with(@class,’xx’)] # 模糊匹配

/div/text()  or /div//text()    # 取文本

/@屬性    # 取屬性

(4)bs4解析經常使用方法回顧

find()      # 找到第一個符合要求的標籤

find_all()  # 找到全部符合要求的標籤

select()    # 根據選擇器找到符合要求的標籤

div a ul li # 多層級選擇器

div>a>ul>li # 單層層級選擇器

三.打碼平臺使用流程

  1. 對攜帶驗證碼的頁面數據進行抓取

  2. 將頁面中的驗證碼進行解析, 將驗證碼圖片下載到本地

  3. 將驗證碼圖片提交給打碼平臺進行識別, 返回識別後的結果

雲打碼平臺使用:

  1. 在官網中進行普通用戶和開發者用戶註冊

  2. 登陸開發者用戶:

    a) 示例代碼下載:開發文檔 --> 調用示例及最新DLL --> PythonHTTP示例下載

    b) 建立一個軟件:個人軟件 --> 添加新的軟件(後期會使用該軟件的祕鑰和id)

  3. 使用示例代碼中的示例代碼對保存本地的驗證碼進行識別

四.移動端數據爬取

博客地址:http://www.javashuo.com/article/p-poferjjp-bx.html

# 詳情步驟請查看視頻:
連接:https://pan.baidu.com/s/1BiNd3IPA44xGszN9n93_hQ 
提取碼:6slk

1.fiddler的設置

  • 端口號和容許抓取其餘機器上的數據包的設置

  • https數據包抓取的設置

2.fiddler證書下載

  • 保證手機和fiddler所在的機器處在同一網段下

  • 下載安全證書,且安裝到手機上。在手機瀏覽器中錄入fiddler機器的ip和fiddler的端口號進行證書的下載。

  • 下載成功後進行證書的安裝

  • 詳細步驟請參考 博客

3.局域網設置

  • 將手機的網絡和端口號設置成fiddler電腦的ip和fiddler的端口號

  • 測試:
    • 開啓fiddler,抓取手機請求的網絡包

五.Scrapy重點回顧

1.持久化存儲操做

(1)基於終端指令的持久化存儲

scrapy crawl 爬蟲名稱 -o xxx.json
scrapy crawl 爬蟲名稱 -o xxx.xml
scrapy crawl 爬蟲名稱 -o xxx.csv

(2)基於管道的持久化存儲

1. 將爬取到的數據封裝在item對象中

2. 使用yield將item提交給管道

3. 在管道文件中的process_item方法中,將item中的數據進行持久化存儲操做

面試題:若是最終須要將爬取到的數據值一份存儲到磁盤文件,一份存儲到數據庫中,則應該如何操做scrapy?

  • 管道文件中的代碼爲:
#該類爲管道類,該類中的process_item方法是用來實現持久化存儲操做的。
class DoublekillPipeline(object):

    def process_item(self, item, spider):
        #持久化操做代碼 (方式1:寫入磁盤文件)
        return item

#若是想實現另外一種形式的持久化操做,則能夠再定製一個管道類:
class DoublekillPipeline_db(object):

    def process_item(self, item, spider):
        #持久化操做代碼 (方式1:寫入數據庫)
        return item
    
    
"""
須要注意的是, 在pipelines.py文件中, 若是pipeline要把該數據存儲到不一樣的數據庫, 就須要在pipelines.py文件中建立多個類, item會在每個類中的process_item方法中進行傳遞(經過process_item方法中的return item), 所以除了最後一個類的process_item方法能夠不return item外, 其他的類都必須return item
"""
  • 在settings.py開啓管道操做代碼爲:
#下列結構爲字典,字典中的鍵值表示的是即將被啓用執行的管道文件和其執行的優先級。
ITEM_PIPELINES = {
   'doublekill.pipelines.DoublekillPipeline': 300,
    'doublekill.pipelines.DoublekillPipeline_db': 200,
}


"""
上述代碼中,字典中的兩組鍵值分別表示會執行管道文件中對應的兩個管道類中的process_item方法,實現兩種不一樣形式的持久化操做。
"""

2.基於scrapy的請求

(1)手動get請求發送

yield scrapy.Request(url,callback)

# 參數說明:
url: 請求的url
callback: 指定方法對請求到的頁面進行解析操做

(2)post請求發送

重寫父類的start_request方法,該方法會被調度器默認調用,在該方法中能夠經過yield scrapy.FormRequest(url,callback,formdata)進行post請求發送。

  • 參數formdata爲post請求攜帶的參數,類型爲字典。

(3)何時會須要使用請求傳參?

  • 當需求中須要解析的數據值不在同一個頁面中時, 必須用請求傳參進行處理.

  • 實現方式:yield scrapy.Request(url,callback,meta), 使用meta參數能夠將item對象傳遞給callback指定的回調方法中. meta爲字典類型.

(4)UA池和代理池

博客地址: http://www.javashuo.com/article/p-mbfwxnkq-dd.html

  • 使用UA池和代理池的目的:
    • 目的在於防止爬取網站的反爬蟲策略
  • UA池操做流程:
    • (1) 在下載中間件中攔截請求
    • (2) 將攔截到的請求的請求頭信息中的UA進行篡改假裝
    • (3) 在配置文件中開啓中間件
  • 代理池操做流程:
    • (1) 在下載中間件中攔截請求
    • (2)將攔截到的請求ip修改爲某一代理ip
    • (3)在配置文件中開啓中間件

(5)scrapy中selenium的應用

博客地址: https://www.cnblogs.com/bobo-zhang/p/10013045.html

原理分析

當引擎將國內板塊url對應的請求提交給下載器後, 下載器進行網頁數據的下載, 而後將下載到的頁面數據封裝到response中, 提交給引擎, 引擎將response再轉交給Spiders. Spiders接受到的response對象中存儲的頁面數據裏是沒有動態加載的新聞數據的, 要想獲取動態加載的新聞數據, 則須要在下載中間件中對下載器提交給引擎的response響應對象進行攔截, 且對其內部存儲的頁面數據進行篡改, 修改爲攜帶了動態加載出的新聞數據, 而後將被篡改的response對象最終交給Spiders進行解析操做.

selenium在scrapy中的使用流程

  • 重寫爬蟲文件的構造方法, 在該方法中使用selenium實例化一個瀏覽器對象(由於瀏覽器對象只須要被實例化一次, 因此選擇把它寫在構造方法__init__中)

  • 重寫爬蟲文件的closed(self, spider)方法, 在其內部關閉瀏覽器對象. 該方法是在爬蟲結束時被調用的.

  • 重寫下載中間件的process_response方法, 讓該方法對響應對象進行攔截, 並篡改response中存儲的頁面數據.

  • 在配置文件中開啓 下載中間件.

(6)分佈式爬蟲實現步驟:

  • 導包
from scrapy_redis.spiders import RedisCrawlSpider
  • 將爬蟲類的父類修改爲RedisCrawlSpider

  • 將起始url列表註釋, 添加一個redis_key(調度器隊列的名稱)的屬性

  • 對redis數據庫配置文件redisxxx.conf進行配置:
    • # bind 127.0.0.1
    • protected-mode no
  • 對項目中settings進行配置

    • a) 配置redis服務器的ip和端口號:

      • REDIS_HOST = 'redis服務的ip地址'
        REDIS_PORT = 6379
        # REDIS_PARAMS = {‘password’:’123456’}
    • b) 配置使用scrapy-redis組件中的調度器:

      • # 使用scrapy-redis組件的去重隊列
        DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
        
        # 使用scrapy-redis組件本身的調度器
        SCHEDULER = "scrapy_redis.scheduler.Scheduler"
        
        # 是否容許暫停
        SCHEDULER_PERSIST = True
    • c) 配置使用scrapy-redis組件中的管道:

      • ITEM_PIPELINES = {
          #'wangyiPro.pipelines.WangyiproPipeline': 300,
          'scrapy_redis.pipelines.RedisPipeline': 400,
        }
    • d) 開啓redis數據庫的服務: redis-server 配置文件

    • e) 執行爬蟲文件: scrapy runspider wangyi.py

    • f) 向調度器的隊列中扔一個起始url:

      - i. 開啓redis客戶端
      
      - ii. lpush 爬蟲文件名稱 起始url

六.常見問題

1.如何顯著提高爬蟲的效率

1. 使用性能更好的機器

2. 使用光纖網絡

3. 多進程

4. 多線程

5. 分佈式

2.基於requests模塊的多線程爬取

基於requests模塊的多線程爬取建議你們使用`multiprocessing.dummy.pool線程池, 爬取效率會顯著提高.

代碼展現:

import requests
from bs4 import Beautiful
#導入線程池
from multiprocessing.dummy import Pool

pool = Pool()#實例化線程池對象
#發起首頁請求
page_text = requests.get(url='xxx')
#使用bs4解析首頁中全部的a標籤
soup = Beautiful(page_text)
a_list = soup.select('a')
#將a標籤的href屬性值和域名拼接,造成完整的url
url_list = ['www.xxx.com/'+url['href'] for url in a_list]
#封裝請求函數,該函數能夠獲取請求對應的頁面數據
request_page_text = lambda link:requests.get(link).text

#使用線程池的map方法異步進行請求發送,切獲取響應回來的頁面數據
page_text_list = pool.map(request_page_text, url_list)

#使用線程池異步進行解析操做
get_data = lambda data:parse(data)
pool.map(get_data, page_text_list)

#數據解析方法
def parse(data):
    pass

3.如何提高scrapy的爬取效率

(1)增長併發

默認scrapy開啓的併發線程爲32個, 能夠適當進行增長. 在settings配置文件中修改`CONCURRENT_REQUESTS = 100值爲100, 併發設置成了爲100.

(2)下降日誌級別

在運行scrapy時, 會有大量日誌信息的輸出, 爲了減小CPU的使用率. 能夠設置log輸出信息爲INFO或者ERROR. 在配置文件中編寫: LOG_LEVEL = ‘INFO’

(3)禁止cookie

若是不是真的須要cookie, 則在scrapy爬取數據時能夠進制cookie從而減小CPU的使用率, 提高爬取效率. 在配置文件中編寫: COOKIES_ENABLED = False.

(4)禁止重試

對失敗的HTTP進行從新請求(重試)會減慢爬取速度, 所以能夠禁止重試. 在配置文件中編寫: RETRY_ENABLED = False

(5)減小下載超時

若是對一個很是慢的連接進行爬取, 減小下載超時能夠能讓卡住的連接快速被放棄, 從而提高效率. 在配置文件中進行編寫: DOWNLOAD_TIMEOUT = 10 超時時間爲10s.

4.經常使用的代理ip網站, 及其代理IP的價格

i. 全國代理IP網:

  • 動態代理IP

  • 長效代理IP

ii. 西祠代理網:

  • 套餐價格:

iii. 快代理網:

  • 套餐價格:

七. 簡歷中爬蟲項目的編寫

1.關於爬取數據類型的問題

常見的爬取數據類型

  • 電商類的商品信息
    • a) 數據來源網站: 京東, 天貓
  • 資訊類的新聞信息
    • a) 網易新聞, 騰訊新聞, 今日頭條等
  • 音樂類的歌詞、歌名、做者信息
    • a) 網易音樂, qq音樂等
  • 醫療器械類的參數信息
  • 氣象類的天氣信息

2.爬取數據量級的問題

  • 針對於百萬量級的數據:
    • a) 基於requests模塊進行爬取, 時長爲2小時左右
    • b) 基於分佈式機羣(3臺), 時長爲0.3小時左右
    • c) 通常公司生產環節中, 數據量過百萬, 則通常會使用分佈式進行數據爬取

3.簡歷中相關爬蟲項目(Demo)

(1)項目名稱: 潮流穿衣搭配數據採集

(2)項目描述:

本項目採用scrapy框架對愛搭配網和穿衣打扮網等網站導航頁下全部大類、小類中的相關子連接, 以及連接頁面的相關內容進行爬取, 將數據寫入數據庫, 提供給公司作參考數據.

(3)責任描述:

a. 負責信息數據的爬取

b. 負責分析數據爬取的過程

c. 負責分析網站的反爬技術, 並提供反反爬策略

d. 採用線程池進行數據爬取, 採集了13w條數據

e. 負責將採集到的數據進行數據分析整理

4.項目名稱: xxx新聞推薦系統數據採集

(1)項目描述:

本項目採用基於RedisCrawlSpider的分佈式爬蟲, 對網易新聞、頭條、新浪新聞等網站進行大類板塊下新聞資訊數據的爬取, 將爬取到的數據調用百度AI接口進行關鍵字提取和文章分類檢索. 設計庫表進行數據存儲.

(2)責任描述:

a. 搭建5臺分佈式機羣進行新聞數據爬取

b. 分析數據爬取過程, 設計反反爬策略

c. 將分佈爬取到的近30w條數據進行數據清洗和異常值過濾

d. 調用百度AI對新聞數據進行關鍵字提取和文章分類

相關文章
相關標籤/搜索