我们接着说这个爬虫的工具scrapy

1.shell对象和selector对象

scrapy shell就是一个交互式的终端,作用:可以很好的调试,启动:scrapy shell url。

如果url有参数,用引号把url包起来

2.选择器

selector
xpath
extract:返回unicode字符串 css(此处是css选择器)
re(此处是正则)

在我们爬取数据时,数据时分开的,我这里的分开是说数据不在同一个页面,但是呢,我们保存的时候在一个文件。
这个时候,我们就使用到了本篇博客中的方法,mate。
我们可以把爬取的一个页面的值传到第二个页面,然后和第二个页面的数据一起保存。
这个方法是我目前学习到的一种,可能后期还会有更好的方法。这个其一,本篇博客的学习,

其二是写入文件的pipline方法有所改变。一开始我们学习的是打开文件写入。也就是写入多少次,打开多少次,这样会影响爬虫写入文件的性能,所以,我们有个本篇的第二种方法,就是爬虫开启,然后我们打开文件,等爬虫结束,我们关闭文件。

如下案例代码:

spider代码,我会把代码分隔开来解释

# -*- coding: utf-8 -*-
import scrapy
from ..items import TencentItem
class TencentSpider(scrapy.Spider):

这个是文件代码头,不需要过多解释。

name = 'tencent'
# allowed_domains = ['https://hr.tencent.com/position.php?&start=0#a']
start_urls = ['https://hr.tencent.com/position.php?&start=0#a']
base_url = 'https://hr.tencent.com/'

start_urls参数是必须要有的,是爬取数据的第一个页面的url,参数名称必须是start_urls。

xpath('//tr[@class="even"]/td[1]/a/text() | //tr[@class="odd"]/td[1]/a/text()').extract()
types = response.xpath('//tr[@class="even"]/td[2]/text() | //tr[@class="odd"]/td[2]/text()').extract()
nums = response.xpath('//tr[@class="even"]/td[3]/text() | //tr[@class="odd"]/td[3]/text()').extract()
address = response.xpath('//tr[@class="even"]/td[4]/text() | //tr[@class="odd"]/td[4]/text()').extract()
times = response.xpath('//tr[@class="even"]/td[5]/text() | //tr[@class="odd"]/td[5]/text()').extract()
info_urls = response.xpath('//tr[@class="even"]/td[1]/a/@href | //tr[@class="odd"]/td[1]/a/@href').extract()

response是请求完start_urls之后返回的页面结果,然后我们使用xpath来定位到自己想要的元素数据,保存到某个参数。

items = dict()
for name, type, num, addres, time, info_url in zip(names, types, nums, address, times, info_urls):
items['name'] = name
items['type'] = type
items['num'] = num
items['address'] = addres
items['time'] = time

我们把数据保存到一个字典,便于后续数据保存。

request = scrapy.Request(url=self.base_url + info_url, callback=self.info_pares)
request.meta['item'] = items#给下一个路由传值
yield request
#下一页
next_url = response.xpath('//a[@id="next"]/@href').extract_first()
if next_url:
yield scrapy.Request(url=self.base_url+next_url,callback=self.parse)

爬取页面下,分页的数据,必须要知道分页的规则,这个是请求分页的比较巧的方法,大家可以看看有没有其他的方法,评论一下。

def info_pares(self, response):
info = dict()
info['squareli'] = response.xpath('//table[@class="tablelist textl"]/tr[3]/td/ul/li/text()').extract()
info['lightblue'] = response.xpath('//table[@class="tablelist textl"]/tr[4]/td/ul/li/text()').extract()
items = response.meta['item']#接收值
item = TencentItem()
item['name'] = items['name']
item['type'] = items['type']
item['num'] = items['num']
item['address'] = items['address']
item['time'] = items['time']
item['info'] = info
yield item

接收到值,后面传给通道pip,保存到数据库或者文件。

pipelines代码:

# -*- coding: utf-8 -*-
import json
class MyspiderPipeline(object):

爬虫运行的时候打开

def open_spider(self,spider):
self.f = open('item.json','w',encoding='utf-8')

这个方法是必须实现的

open('item.json','a+',encoding='utf-8') as f:
# # f.write(json.dumps(item)+'\n')#老写发
# f.write(str(item)+'\n')#新写法
# return item
#激活才可以写入到文件,激活在settings中的67
self.f.write(json.dumps(dict(item),ensure_ascii=False)+'\n')
return item

爬虫结束时关闭

def close_spider(self,spider):
self.f.close()