我這裏要講的是在確認程序語法無誤後,以故意製造 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)