8-4 selenium集成到scrapy中
其實也沒什么好說的直接上代碼
這是在middlewares.py中定義的一個class:
1 from selenium.common.exceptions import TimeoutException 2 from scrapy.http import HtmlResponse #傳遞js加載后的源代碼,不會返回給download 3 class JSPageMiddleware(object): 4 #通過chrome請求動態網頁 5 def process_request(self, request, spider): 6 if spider.name == "JobBole": 7 try: 8 spider.browser.get(request.url) 9 except TimeoutException: 10 print('30秒timeout之后,直接結束本頁面') 11 spider.browser.execute_script('window.stop()') 12 import time 13 time.sleep(3) 14 print("訪問:{0}".format(request.url)) 15 16 return HtmlResponse(url=spider.browser.current_url, body=spider.browser.page_source, encoding="utf-8", request=request) 17 '''編碼默認是unicode'''
spider中的代碼:
1 name = "JobBole" 2 allowed_domains = ["jobbole.com"] 3 start_urls = ['http://blog.jobbole.com/all-posts/'] 4 5 def __init__(self): 6 '''chrome放在spider中,防止每打開一個url就跳出一個chrome''' 7 self.browser=webdriver.Chrome(executable_path='E:/chromedriver.exe') 8 self.browser.set_page_load_timeout(30) 9 super(JobboleSpider, self).__init__() 10 dispatcher.connect(self.spider_close,signals.spider_closed) 11 12 def spider_close(self,spider): 13 #當爬蟲退出的時候關閉Chrome 14 print("spider closed") 15 self.browser.quit()
把selenium集成到scrapy中主要改變的就是這兩處地方。
以上的在scrapy中嵌入selenium的chrome並不是異步的,所以效率會變差。
這里都是部分代碼,完整代碼鏈接:https://github.com/pujinxiao/jobbole_spider
8-5 其余動態網頁獲取技術介紹-chrome無界面運行、scrapy-splash、selenium-grid, splinter
1.chrome無界面運行
主要是以下代碼(不能在windows上運行):
1 from pyvirtualdisplay import Display 2 display = Display(visible=0, size=(800, 600)) 3 display.start() 4 5 browser = webdriver.Chrome() 6 browser.get()
2.scrapy-splash
Splash是一個Javascript渲染服務。它是一個實現了HTTP API的輕量級瀏覽器,Splash是用Python實現的,同時使用Twisted和QT。Twisted(QT)用來讓服務具有異步處理能力,以發揮webkit的並發能力。
可以在scrapy中處理ajax來抓取動態的數據,沒有chrome那么穩定。
更多介紹 傳送門
3.selenium-grid(自行百度查看)
4.splinter
8-6 scrapy的暫停與重啟
在命令行:scrapy crawl lagou -s JOBDIR=job_info/001
只要按一次 ctrl+c 就會暫停爬蟲,重新啟動一樣的命令再運行一邊。
會生成以下文件:
在requests.queue文件中有以下文件:
如果要保存在不同的文件那就修改不同路徑就好了,spider會重新從第一個url開始爬取。
8-7 scrapy url去重原理
相關代碼都在dupefilter.py中
其實就是做了一個哈希摘要,放在set中,去查新的url是否在set中。
8-8 scrapy telnet服務
詳細的介紹在scrapy文檔中都有,傳送門。
你可以在cmd中監聽spider中的變量。先要在控制面板中打開telnet客戶端和服務端,在cmd中輸入 telnet localhost 6023 即可。
但是不知道為什么,win10中沒有telnet服務端,而且我打開telnet的后不能輸入字母(待解決)
8-9 spider middleware 詳解
平時也沒怎么用到,理解的也不夠透徹。scrapy的中文文檔中也寫的很詳細,傳送門,大家可以參考。
主要是這么幾個文件:
depth.py:爬取深度的設置
httperror.py:狀態的設置,比如是不是要把404的也抓取下來,等等。
其他的話自己了解把,需要的時候在深入了解做下筆記。
8-10 scrapy的數據收集 和 8-11 scrapy信號詳解
文檔說明,數據收集傳送門。在工作中沒有用到,用到了再細寫,這樣理解更好。
scrapy信號是非常重要的,之前在selenium中chrome就是用信號量,當spider關閉時,再關閉chrome。信號量詳解傳送門。
實例就是伯樂在線的例子:
部分代碼如下(可以借鑒,其實也包含了8-11信號量的代碼):
1 #收集伯樂在線所有404的url以及404頁面數 2 handle_httpstatus_list = [404] 3 4 def __init__(self, **kwargs): 5 self.fail_urls = [] 6 dispatcher.connect(self.handle_spider_closed, signals.spider_closed) 7 8 def handle_spider_closed(self, spider, reason): 9 self.crawler.stats.set_value("failed_urls", ",".join(self.fail_urls)) 10 11 def parse(self, response): 12 """ 13 1. 獲取文章列表頁中的文章url並交給scrapy下載后並進行解析 14 2. 獲取下一頁的url並交給scrapy進行下載, 下載完成后交給parse 15 """ 16 #解析列表頁中的所有文章url並交給scrapy下載后並進行解析 17 if response.status == 404: 18 self.fail_urls.append(response.url) 19 self.crawler.stats.inc_value("failed_url") 20 21 post_nodes = response.css("#archive .floated-thumb .post-thumb a") 22 for post_node in post_nodes: 23 image_url = post_node.css("img::attr(src)").extract_first("") 24 post_url = post_node.css("::attr(href)").extract_first("") 25 yield Request(url=parse.urljoin(response.url, post_url), meta={"front_image_url":image_url}, callback=self.parse_detail)
全部代碼移步github:https://github.com/pujinxiao/jobbole_spider/blob/master/bole/spiders/JobBole.py
結果: (錯誤的url也被統計記錄下來了)
8-12 scrapy擴展開發
擴展之間看文檔,傳送門。
作者:今孝
出處:http://www.cnblogs.com/jinxiao-pu/p/6815845.html
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接。
覺得好就點個推薦吧!