通常在做项目的过程中,在items.py中进行数据建模
在items.py文件中定义要提取的字段:
class MyspiderItem(scrapy.Item):
name = scrapy.Field() # 讲师的名字
title = scrapy.Field() # 讲师的职称
desc = scrapy.Field() # 讲师的介绍
模板类定义以后需要在爬虫中导入并且实例化,之后的使用方法和使用字典相同
job.py:
from myspider.items import MyspiderItem # 导入Item,注意路径
...
def parse(self, response)
item = MyspiderItem() # 实例化后可直接使用
item['name'] = node.xpath('./h3/text()').extract_first()
item['title'] = node.xpath('./h4/text()').extract_first()
item['desc'] = node.xpath('./p/text()').extract_first()
print(item)
注意:
- 创建项目
scrapy startproject 项目名- 明确目标
在items.py文件中进行建模- 创建爬虫
3.1 创建爬虫
scrapy genspider 爬虫名 允许的域
3.2 完成爬虫
修改start_urls
检查修改allowed_domains
编写解析方法- 保存数据
在pipelines.py文件中定义对数据处理的管道
在settings.py文件中注册启用管道
对于要提取如下图中所有页面上的数据该怎么办?
回顾requests模块是如何实现翻页请求的:
scrapy实现翻页的思路:
通过爬取网易招聘的页面的招聘信息,学习如何实现翻页请求
地址:https://hr.163.com/position/list.do
# False表示忽略网站的robots.txt协议,默认为True
ROBOTSTXT_OBEY = False
# scrapy发送的每一个请求的默认UA都是设置的这个User-Agent
USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36'
在爬虫文件的parse方法中:
......
# 提取下一页的href
next_url = response.xpath('//a[contains(text(),">")]/@href').extract_first()
# 判断是否是最后一页
if next_url != 'javascript:void(0)':
# 构造完整url
url = 'https://hr.163.com/position/list.do' + next_url
# 构造scrapy.Request对象,并yield给引擎
# 利用callback参数指定该Request对象之后获取的响应用哪个函数进行解析
yield scrapy.Request(url, callback=self.parse)
......
scrapy.Request(url[,callback,method="GET",headers,body,cookies,meta,dont_filter=False])
meta的作用:meta可以实现数据在不同的解析函数中的传递
在爬虫文件的parse方法中,提取详情页增加之前callback指定的parse_detail函数:
def parse(self,response):
...
yield scrapy.Request(detail_url, callback=self.parse_detail,meta={"item":item})
...
def parse_detail(self,response):
#获取之前传入的item
item = resposne.meta["item"]
proxy
,表示代理ip,关于代理ip的使用我们将在scrapy的下载中间件的学习中进行介绍wangyi/spiders/job.py
import scrapy
from wangyi.items import WangyiItem
class JobSpider(scrapy.Spider):
name = 'job'
# 2、检查修改域名
allowed_domains = ['163.com']
# 1、修改起始url
start_urls = ['https://hr.163.com/position/list.do']
# 3、解析数据
def parse(self, response):
# 提取数据
# 获取所有职位节点列表
node_list = response.xpath('//*[@class="position-tb"]/tbody/tr')
# print(len(node_list))
# 遍历节点列表,通过枚举来过滤掉没用的节点
for num,node in enumerate(node_list):
# print(num,node)
# 设置过滤条件,将目标节点获取出来
if num % 2 ==0:
item = WangyiItem()
item['name'] = node.xpath('./td[1]/a/text()').extract_first()
# item['link'] = "https://hr.163.com/" + node.xpath('./td[1]/a/@href').extract_first()
# response.urljoin()用来拼接相对路径的url,可以理解成自动补全
item['link'] = response.urljoin(node.xpath('./td[1]/a/@href').extract_first())
item['depart'] = node.xpath('./td[2]/text()').extract_first()
item['category'] = node.xpath('./td[3]/text()').extract_first()
item['type'] = node.xpath('./td[4]/text()').extract_first()
item['address'] = node.xpath('./td[5]/text()').extract_first()
# strip()方法去掉字符串前后的空格
item['num'] = node.xpath('./td[6]/text()').extract_first().strip()
item['date'] = node.xpath('./td[7]/text()').extract_first()
# print(item)
# yield item
# 构建详情页面的请求
yield scrapy.Request(
url = item['link'],
callback = self.parse_detail,
meta = {'item':item}
)
# 模拟翻页
part_url = response.xpath('/html/body/div[2]/div[2]/div[2]/div/a[last()]/@href').extract_first()
# 判断终止条件
if part_url != 'javascript:void(0)':
next_url = response.urljoin(part_url)
# 构建请求对象,并且返回给引擎
yield scrapy.Request(
url = next_url,
callback = self.parse
)
# 定义详情页面的数据解析方法
def parse_detail(self,response):
# 将meta传参获取
# print('------------------',response.meta['item'])
item = response.meta['item']
# 提取剩余字段数据
item['duty'] = ''.join(response.xpath('/html/body/div[2]/div[2]/div[1]/div/div/div[2]/div[1]/div/text()').extract()).strip()
item['require'] = ''.join(response.xpath('/html/body/div[2]/div[2]/div[1]/div/div/div[2]/div[2]/div/text()').extract()).strip()
# print(item)
# 返回给引擎
yield item
wangyi/items.py
# Define here the models for your scraped items
#
# See documentation in:
# https://docs.scrapy.org/en/latest/topics/items.html
import scrapy
class WangyiItem(scrapy.Item):
# define the fields for your item here like:
name = scrapy.Field() # 职位名称
link = scrapy.Field() # 点击链接
depart = scrapy.Field() # 所属部门
category = scrapy.Field() # 职位类型
type = scrapy.Field() # 工作类型
address = scrapy.Field() # 工作地点
num = scrapy.Field() # 招聘人数
date = scrapy.Field() # 发布时间
duty = scrapy.Field() # 岗位描述
require = scrapy.Field() # 岗位要求