我这里要讲的是在确认程序语法无误后,以故意制造 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)