爬蟲項目經驗總結

前言

  重新數據庫 mongodb 到基於內存的 key-value 數據庫 Redis,從 scrapy 爬蟲框架到 re 正則表達式模塊,尤爲正則,之前不會寫的時候老是依賴 string 的各類方法,部分時候顯得有些繁瑣,會正則了以後在字符串的匹配、查找、替換、分隔方面打開了另外一扇便捷之窗。另外,將 Redis 引入爬蟲架構來實現分佈式,也算是一個技術理念的突破吧,也爲後面研究高併發站點打下了基礎。
 
  其實前面說了那麼多唬人的東西,用的時候卻是沒有說有實在適應不來的,做爲一個敲了快三年代碼的磚工來講算不上什麼技術攻堅,可能在 Nosql 和正則模塊(包括正則語法和 re 模塊)投入的精力相對多一點。業務上,對於網頁結構的分析和一個高覆蓋率 url 爬取策略的制定仍是得跟有經驗的開發人員多討論,就爬蟲來講,技術不是重點,更多的是對站點頁面跳轉套路的分析。
  
  下面就結合實際開發中常遇到的一些問題分節對爬蟲這塊的注意事項作一個簡要講解。

取消合法性檢驗以改進爬取方案

  我這裏要講的是在確認程序語法無誤後,以故意製造 AtttributeError 來完善爬取策略,算不上什麼方案,一點寫法上的小技巧吧。前端

  這個報錯具體解釋起來就是 'NoneType' object has no attribute ,相似於 java 裏面的空指針異常。首先,解決這個異常的方式很簡單,好比讓 soup 在查找上一級標籤的時候作一次是否爲空的判斷,若是不爲空則繼續查找到下一級目標:(if parentNode:   ...)。但實際上最開始寫這塊內容的時候要避免這種條件判斷,由於咱們並不知道咱們要找的目標在該類網頁當中是否只存在一種結構,有可能有的頁面壓根兒沒那個標籤,也有可能標籤名不同或者類名變了等等狀況,這須要咱們在測試過程當中去記錄下全部出錯的頁面,逐一排查這些頁面的特殊結構,這樣纔能有效地保證咱們所爬取的頁面覆蓋面更廣,數據更全。下面拿實際代碼舉個例子:java

soup = BeautifulSoup(response.body_as_unicode(),'lxml')
citys = soup.find('div',class_="piList").find_all('span') for city in citys:   href = city.find('a').get('href')
  yield Request(href, callback=self.get_url)

  這裏在獲取網頁中城市的連接的時候,並無首先去對 span 的祖先(前端術語) class 爲 piList 是否存在作判斷,由於在爬這類的網頁的時候固然會有可能說是部分頁面的城市信息壓根不放在這裏面,類名爲 piList 的標籤壓根不存在,這時候程序會在這裏報 AtttributeError 但不會影響爬蟲的繼續運行,等整個程序執行完畢,scrapy 會有一個總的出錯統計在日誌的末尾,咱們就順着總數一一找出出錯位置對應的頁面 url 再去瀏覽器找到該頁面,從新分析其文檔結構,或改類名,或改標籤名,最後完善成相似下面的代碼:web

soup = BeautifulSoup(response.body_as_unicode(),'lxml')
city_list = soup.find('div',class_="piList")
if not city_list:
  city_list = soup.find('div',id="citys")
citys = city_list.find_all('span') for city in citys:   href = city.find('a').get('href')   yield Request(href, callback=self.get_url)

關於使用瀏覽器開發者工具查看網頁

  咱們在用瀏覽器的開發者工具分析網頁的時候,最好是在 Sources 下面查看網站源碼,由於咱們爬蟲爬下來的內容是未經瀏覽器渲染的(儘管有這樣的工具,好比 PyQt 中的 webkit)。可是大多數狀況下咱們在 Elements 審查/檢查 窗口看到的內容與 Sources 下面是一致的,並且在這下面進行標籤的查看和文檔結構的分析也更方便,因此可在其下面定位目標後到 Sources 中確認是否能找到,再肯定 beautifulsoup 或 xpath 的寫法,尤爲對於翻頁和經過事件響應跳出的彈窗。
相關文章
相關標籤/搜索