引入
- 在通過scrapy框架進行某些網站資料爬取的時候,往往會碰到頁面動態資料載入的情況發生,如果直接使用scrapy對其url發請求,是絕對獲取不到那部分動態載入出來的資料值。但是通過觀察我們會發現,通過瀏覽器進行url請求傳送則會載入出對應的動態載入出的資料。那麼如果我們想要在scrapy也獲取動態載入出的資料,則必須使用selenium建立瀏覽器物件,然後通過該瀏覽器物件進行請求傳送,獲取動態載入的資料值。
1.案例分析:
- 需求:爬取網易新聞的國內板塊下的新聞資料
- 需求分析:當點選國內超鏈進入國內對應的頁面時,會發現當前頁面展示的新聞資料是被動態載入出來的,如果直接通過程式對url進行請求,是獲取不到動態載入出的新聞資料的。則就需要我們使用selenium例項化一個瀏覽器物件,在該物件中進行url的請求,獲取動態載入的新聞資料。
2.selenium在scrapy中使用的原理分析:
當引擎將國內板塊url對應的請求提交給下載器後,下載器進行網頁資料的下載,然後將下載到的頁面資料,封裝到response中,提交給引擎,引擎將response在轉交給Spiders。Spiders接受到的response物件中儲存的頁面資料裡是沒有動態載入的新聞資料的。要想獲取動態載入的新聞資料,則需要在下載中介軟體中對下載器提交給引擎的response響應物件進行攔截,切對其內部儲存的頁面資料進行篡改,修改成攜帶了動態載入出的新聞資料,然後將被篡改的response物件最終交給Spiders進行解析操作。
3.selenium在scrapy中的使用流程:
1.在spider的構造方法中建立一個瀏覽器物件(作為當前spider的一個屬性) 2.重寫spider的一個方法closed(self,spider),在該方法中執行瀏覽器關閉的操作 3.在下載中介軟體的process_response方法中,通過spider引數獲取瀏覽器物件 4.在中介軟體的process_response中定製基於瀏覽器自動化的操作程式碼(獲取動態載入出來的頁面原始碼資料) 5.例項化一個響應物件,且將page_source返回的頁面原始碼封裝到該物件中 6.返回該新的響應物件
4.程式碼:
爬蟲程式碼:
import scrapy from selenium import webdriver class WangyiSpider(scrapy.Spider): name = 'wangyi' # allowed_domains = ['www.xxx.com'] start_urls = ['http://war.163.com/'] def __init__(self): self.bro = webdriver.Chrome(executable_path=r'F:\上課作業視訊\爬蟲\s15day137爬蟲\chromedriver.exe') def parse(self, response): div_list = response.xpath('//div[@class="data_row news_article clearfix "]') for div in div_list: title = div.xpath('.//div[@class="news_title"]/h3/a/text()').extract_first() print(title) def closed(self,spider): print('關閉瀏覽器物件!') self.bro.quit()
middlewares.py
from scrapy import signals from scrapy.http import HtmlResponse from time import sleep def process_response(self, request, response, spider): # Called with the response returned from the downloader. # Must either; # - return a Response object # - return a Request object # - or raise IgnoreRequest print('即將返回一個新的響應物件!!!') #獲取動態載入出來的資料 bro = spider.bro bro.get(url=request.url) sleep(3) #包含了動態載入出來的新聞資料 page_text = bro.page_source sleep(3) return HtmlResponse(url=spider.bro.current_url,body=page_text,encoding='utf-8',request=request)
settings配置
USER_AGENT = 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36' ROBOTSTXT_OBEY = False DOWNLOADER_MIDDLEWARES = { 'wangyiPro.middlewares.WangyiproDownloaderMiddleware': 543, } LOG_LEVEL = 'ERROR'