解析步骤
对于一个scrapy的实现的步骤
1.修改起始url
2.验证域名
3.在parse中实现爬取逻辑
其中的response为url经过Doloader加载后返回的对象
类型为<class 'scrapy.http.response.html.HtmlResponse'>
print(response.url) # 响应的url
print(response.request.url)# 返回响应的请求的url
print(response.headers)
print(response.request.headers)
print(response.body)
在其中封装了xpath方法,即可以通过xpath方法来对源代码进行解析
实现一个例子,将Itcast中的所有教师信息进行爬取
分析得到每个教师信息都在一个div class =“li_txt”的标签下面
则代码为
def parse(self, response):
# 获取所有教师节点
all_teacher = response.xpath('//div[@class="li_txt"]')#获取每一个教师节点,response有xpath方法
for tea in all_teacher:
name = tea.xpath('./h3/text()').get()# 教师姓名
title = tea.xpath('./h4/text()').get()# 教师职位
desc = tea.xpath('./p/text()').get()# 教师简介
保存数据
这里是在Spider模块中,要想保存数据就要将数据传递到ItemPipeline中进行保存
我们会想到将数据return到Engine中不就可以了么,但是return只能返回一次,如果想翻页,将多个url的数据进行返回,一次可能不太够,这时就要用到yield了
yield {'name':name,'title':title,'desc':desc}# 返回数据
数据这样就返回到ItemPipeline中了
保存数据的步骤,
1.在pipelins.py文件中自定义一个类
2.该类重写process_item方法
3.在process_item中处理
4.完的数据一定要返回给Engine,即return item
5.在settings.py文件中配置相关的管道变量
class ScrapyTextPipeline:
def process_item(self, item, spider):# 这里的item就为上面yield返回的对象
print(item['name'],item['title'],item['desc'])
return item
将其注释全部取消即可
这是一个字典,只有传入创建的不同的管道类,后面的value的值越小执行优先级越高(0-500)之间的数
让后执行命令就可以打印相关信息了
保存数据是要在return item之前进行
因为数据是一条一条传输的,所以文件不能每次传过来一个数据就要打开关闭一次
因为创建的是一个类,可以实现类方法来对文件进行打开关闭
class ScrapyTextPipeline:
def __init__(self):# 构造函数
self.file = open('Itcast.json', 'w', encoding='utf-8')
def process_item(self, item, spider):
self.file.write(json.dumps(item,ensure_ascii=False) + ',\n')
return item
def __del__(self):# 析构函数
self.file.close()
dumps默认为ascii码因为我们存储的数据中含有中文,则要在dumps中限定ensure_ascii为False(默认为True)
又因为数据时一条一条传输的,不叫上换行就会出现整个json文件只有一行,不加上,就会报错误,每次dumps之后就是字符串,直接在后面加上+',\n’即可。
数据建模
在对爬取的数据进行建模,确定要爬取的数据,防止误爬,在定义好之后,系统会自动检查
配合注释可以清晰的知道要抓取那些字段。没有定义的字段不能抓取,在目标字段很短的时候可以使用字典来代替
使用Scrapy中的特定的组件需要Item做支持,如Scrapy中的ImagePipeline管道类
建模步骤:
1.在Items.py中创建一个类,定义要爬取的字段
2.在Spider.py中导入创建的类
3.实例化类,对类中的数据进行赋值,然后返回
注意:返回值不是一个字典类型了,在Pipelines中有使用dumps的要将该返回数据进行强转成dict类型(只有Scrapy中可以这样强转类型)