CrawlSpider的parse_start_url
小编,最近也是学习Scrapy的框架,一头雾水。
记录一下误区。
Scrapy在创建的时候,会有spiders的文件夹,在里面创建我们写的页面分析的代码。
在这个文件里面,类属性中,有name, allowed_domains, start_urls。(下方,小编修改过)
start_urls里面存放的我们的请求队列,之后会被调度器scheduler调用,组成队列,等待下载器的下载。
name = ‘book.zongheng’
# allowed_domains = [‘https://book.zongheng.com’]
start_urls = [‘http://book.zongheng.com/store/c0/c0/b0/u0/p1/v9/s1/t0/u0/i1/ALL.html’,
‘http://book.zongheng.com/store/c0/c0/b0/u0/p6/v9/s1/t0/u0/i1/ALL.html’]
当然,也可以重写请求url队列,通过 start_requests(self):
def start_requests(self):
max_page = 6
for i in range(1, max_page):
url = 'http://book.zongheng.com/store/c0/c0/b0/u0/p' + str(i) + '/v9/s1/t0/u0/i1/ALL.html'
yield Request(url)
返回的request也可以加上callback,也就是回调函数。此时,请求url会发生变化,原来的start_url就会不起作用。
CrawlSpider则是 可以对url进行过滤。这些爬取规则由一个专门的数据结构Rule来进行表示,Rule里面包含着提取和跟进页面的配置,Spider会根据Rule来确定当前的页面中有那些链接需要继续爬取。
小编想,定义两个item。以小说网站为例,第一个item存储每个小说的name和rank(排名)(另一个页面),第二个item存储小说的作者,名字,类型(第一个页面),利用Rule可以将当前页面的所有的小说链接提取出来,并且自动生成Request,在调用哟个专门处理的parse解析函数获取数据,换页的处理用start_requests。
rules = (
# 书的详情页
Rule(LinkExtractor(allow=r’http://book.zongheng.com/book/\d+.html’), callback=‘parse_item’,
follow=True,
),
# 书的列表
# Rule(LinkExtractor(allow=r’http://book.zongheng.com/store/c0/c0/b0/u0/p\d+/v9/s1/t0/u0/i1/ALL.html’),
# callback=‘parse_list_item’,
# follow=True,
# ),
)
# def process_link(self, links):# 匹配到的url进行guolv
# for link in links:
# print(link)
# def process_request(self): # request进行过滤
# pass
# 用来提取每个小说的name,rank,作为Rule的回调函数
def parse_item(self, response):
item = BookInfoItem()
#item[‘domain_id’] = response.xpath(’//input[@id=“sid”]/@value’).get()
#item[‘name’] = response.xpath(’//div[@id=“name”]’).get()
#item[‘description’] = response.xpath(’//div[@id=“description”]’).get()
item[‘book_name’] = response.xpath(’//div[@class=“book-name”]/text()’).extract_first().replace(’\r\n’, ‘’).strip()
item[‘book_rank’] = response.xpath(’//i[@class=“a1”]/text()’).extract_first()
yield item
这个parse用来处理每一个页面中的 众多小说的数据
def parse_list_url(self, response):
item = BookListItem()
item['book_name'] = response.xpath('//div[@class="bookname"]/a/text()').extract()
item['book_auth'] = response.xpath('//div[@class="bookilnk"]/a[1]/text()').extract()
item['book_type'] = response.xpath('//div[@class="bookilnk"]/a[2]/text()').extract()
yield item
# max_page = 6
# for i in range(1, max_page):
# url = 'http://book.zongheng.com/store/c0/c0/b0/u0/p' + str(i) + '/v9/s1/t0/u0/i1/ALL.html'
# yield Request(url, callback=self.parse_list_item)
def start_requests(self):
max_page = 6
for i in range(1, max_page):
url = 'http://book.zongheng.com/store/c0/c0/b0/u0/p' + str(i) + '/v9/s1/t0/u0/i1/ALL.html'
yield Request(url)
小编把name,rank存到MySql里面,另一个存到txt文件里面。但这样写,请求有257次,包括大页面的请求5次和每部小说的请求252次。但是txt文件里面不会有数据。这是因为并没有回调函数的使用。
于是小编加上了回调函数:
def start_requests(self):
max_page = 6
for i in range(1, max_page):
url = 'http://book.zongheng.com/store/c0/c0/b0/u0/p' + str(i) + '/v9/s1/t0/u0/i1/ALL.html'
yield Request(url, callback=self.parse_list_item)
再次请求时,却只有5次大页面的请求,可能是加上callback后,下载内容直接交给对应的spider解析。
后来,小编查阅资料,发现,CrawlSpider提供了非常重要的一个方法,parse_start_url。——当start_urls里卖弄对应的Request得到的Response时,该方法被调用,他会分析Response并返回item或者Request对象(被重新放到Request队列等到被请求)。 只需要佳能上面的parse_list_item方法改成下述名字即可 重写。
```python
def parse_start_url(self, response):
item = BookListItem()
item['book_name'] = response.xpath('//div[@class="bookname"]/a/text()').extract()
item['book_auth'] = response.xpath('//div[@class="bookilnk"]/a[1]/text()').extract()
item['book_type'] = response.xpath('//div[@class="bookilnk"]/a[2]/text()').extract()
yield item