💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
官方文档中入门例子还是要跑一下的,执行一遍之后,可以找出一些当前版本`V1.5`和之前版本之间的差别。我没那么醒目,所以就多执行了几遍。 一些基本的命令一直没有变,例如新建一个爬虫项目的命令是: `scrapy startproject news_scrapy` # news_scrapy是这个爬虫项目的名称 目录如下: news_scrapy/ scrapy.cfg # 这个暂时没用上 news_scrapy/ __init__.py items.py # 这个有用,下表 middlewares.py # 这个暂时没用上 pipelines.py # 大型爬虫用,小爬虫可不用 settings.py # 这个暂时没用上 spiders/Wynews.py # 爬虫叫做Wynews.py __init__.py # 这个暂时没用上 这些代码的核心取自徐阿衡的博客。里面讲了怎样从[网易新闻排行榜](http://news.163.com/rank)爬取新闻。 [TOC] 但是,这些代码并不可以在`scrapy v1.5`上运行,而且我也没找到博主用的是什么版本的`scrapy`,所以,得在博主代码的基础上,做一些修改。 [TOC] 博主在[博客](http://www.shuang0420.com/2016/06/12/%E7%88%AC%E8%99%AB%E6%80%BB%E7%BB%93-%E4%BA%8C-scrapy/)和[Github](https://github.com/Shuang0420/Crawler/tree/master/wynews)上的代码并不完全一样,所以也提供了一些线索,即核心的部分不会更改。不一样的地方有几个: [TOC] 在`Github`上,`item.py`的代码如下: ``` import scrapy class WynewsItem(scrapy.Item): # 定义了一个 WynewsItem 类 category = scrapy.Field() url = scrapy.Field() secondary_title = scrapy.Field() secondary_url = scrapy.Field() pass ``` 这个`WynewsItem`类,用在`spiders/Wynews.py `代码里的`second_parse`方法里 ``` def second_parse(self,response): ...... for i in page: item = WynewsItem() # WynewsItem类用在这里 item['category'] = item_1['category'].encode('utf8') item['url'] = item_1['url'].encode('utf8') item['secondary_title'] = i.xpath('text()').extract_first().encode('utf8') item['secondary_url'] = i.xpath('@href').extract_first().encode('utf8') #print i.xpath('text()').extract(),i.xpath('@href').extract() items.append(item) return items ``` [TOC] 在博客里,`item.py`的代码如下: ``` import scrapy class NewsScrapyItem(scrapy.Item): # 定义了一个 NewsScrapyItem 类 category = scrapy.Field() url = scrapy.Field() secondary_title = scrapy.Field() secondary_url = scrapy.Field() #text = Field() ``` 这个`NewsScrapyItem`类,并没有体现在`spiders/Wynews.py `代码里的`second_parse`方法里,而是多了一个`DidiScrapyItem`类: ``` def second_parse(self,response): ...... for i in page: item = DidiScrapyItem() # 反而多了一个DidiScrapyItem类 item['category'] = item_1['category'].encode('utf8') item['url'] = item_1['url'].encode('utf8') item['secondary_title'] = i.xpath('text()').extract_first().encode('utf8') item['secondary_url'] = i.xpath('@href').extract_first().encode('utf8') #print i.xpath('text()').extract(),i.xpath('@href').extract() items.append(item) return items ``` 如果按照博客上的代码执行,程序会报错,找不到`DidiScrapyItem`这个类,因为程序里并没有定义这个类。 然后,按照`Github`上的代码更改后,这个报错就没有了。 [TOC] 但是在报错的道路上,问题一直存在,这些问题和博主就没关系了,因为是版本升级造成的。 问题是`spiders/Wynews.py `代码里的`parse`和`second_parse`两个方法里,`Scrapy v1.5.1`的几个内建函数已经没有了,被整合了,如果按旧版本操作,就会报错。 `spiders/Wynews.py `报错的位置在: ``` import sys reload(sys) sys.setdefaultencoding('utf8') import scrapy from scrapy.spider import BaseSpider # 这里会报错 from scrapy.selector import HtmlXPathSelector # 这里会报错 from wynews.items import WynewsItem from scrapy.http import Request # 这里会报错 class WynewsSpider(BaseSpider): name = "Wynews" def __init__(self, category=None, *args, **kwargs): super(WynewsSpider, self).__init__(*args, **kwargs) self.start_urls = ['http://news.163.com/rank/'] if category=='all': self.category='' else: self.category = category def parse(self,response): html = HtmlXPathSelector(response) # 这里会报错 page = html.xpath('//div[@class="subNav"]/a') ...... yield Request(url=item['url'],meta={'item_1': item},callback=self.second_parse) # 这里会报错 def second_parse(self,response): item_1= response.meta['item_1'] html = HtmlXPathSelector(response) # 这里会报错 ...... return items ``` 这些报错就得参考`Scrapy 1.5.1`的[官方文档](https://doc.scrapy.org/en/latest/intro/tutorial.html)了。更改后`spiders/Wynews.py `的代码如下: ``` # -*- coding: utf-8 -*- import scrapy from news_scrapy.items import WynewsItem class WynewsSpider(scrapy.Spider): name = "Wynews" start_urls = ['http://news.163.com/rank/'] def parse(self,response): page = response.xpath('//div[@class="subNav"]/a') for i in page: item = dict() item['category'] = i.xpath('text()').extract_first() item['url'] = i.xpath('@href').extract_first() print item['category'],item['url'] yield scrapy.Request(url=item['url'],meta={'item_1': item},callback=self.second_parse) def second_parse(self,response): item_1= response.meta['item_1'] page = response.xpath('//tr/td/a') items = [] for i in page: item = WynewsItem() item['category'] = item_1['category'].encode('utf8') item['url'] = item_1['url'].encode('utf8') item['secondary_title'] = i.xpath('text()').extract_first().encode('utf8') item['secondary_url'] = i.xpath('@href').extract_first().encode('utf8') #print i.xpath('text()').extract(),i.xpath('@href').extract() items.append(item) return items ``` 总之,新版`Scrapy 1.5.1`隐藏了很多之前版本需要显式声明的部分。我们再检查一下从[网易新闻排行榜](http://news.163.com/rank)爬取新闻爬取的效果。 `scrapy crawl Wynews -o items.json ` [TOC] ![](https://box.kancloud.cn/7347d547788b230dc607bba5314e4057_1219x534.png) [TOC] 一切OK!