目录
1.安装scrapy
2.创建项目
3.工程目录结构
4.工程目录结构详情
5.创建爬虫文件
6.编写对应的代码在爬虫文件中
7.执行工程
8.scrapy数据解析
9.持久化存储
10.管道完整代码
pip install scrapy
scrapy startproject proname #proname就是你的项目名称
spiders:存放爬虫代码目录。
__init__.py:爬虫项目的初始化文件,用来对项目做初始化工作。
items.py:爬虫项目的数据容器文件,用来定义要获取的数据、保存数据。
pipelines.py:爬虫项目的管道文件,用来对items中的数据进行进一步的加工处理。
settings.py:爬虫项目的设置文件,包含了爬虫项目的设置信息。
middlewares.py:爬虫项目的中间件文件。
scrapy.cfg:爬虫项目的配置文件
1. cd duanziPro # 进入项目
2. 创建爬虫源文件:scrapy genspider duanzi www.xxx.com # 后面这个域名随便写,可更改
import scrapy
from duanziPro.items import DuanziproItem
class DuanziSpider(scrapy.Spider):
name = 'duanzi'
# allowed_domains = ['www.xxx.com']
start_urls = ['https://duanzixing.com/']
# 基于管道的持久化存储
def parse(self, response): # 基于终端指令的持久化存储
all_data = []
# 数据解析名称内容
article_list = response.xpath('/html/body/section/div/div/article')
for article in article_list:
# extract_first():将列表中的第一个列表元素表示的selector对象中的data元素取出
title = article.xpath('./header/h2/a/text()').extract_first()
content = article.xpath('./p[2]/text()').extract_first()
# 实例化一个item类型的对象,将解析到的数据存储到该对象当中
item = DuanziproItem()
# 不可以通过.的形式调用属性
item['title'] = title
item['content'] = content
# 将item对象提交给管道
yield item
scrapy crawl duanzi # 这里这个duanzi是爬虫源文件的名字
执行工程后,默认会输出工程所有的日志信息,我们可以指定类型日志输出,多数情况我们只看报错,在seethings.py中加上 LOG_LEVEL = 'ERROR'。为了避免后续出问题,我们把seethings里面的ROBOTSTXT_OBEY = TRUE (robots协议默认是true我们把它改为false),seethings里还有一个 USER_AGENT(也就是 我们的UA伪装,给他加上 )
在爬虫文件中使用response.xpath('xpath表达式')
scrapy封装的xpath和etree中的xpath的区别:scrapy中的xpath直接将定位到的标签中存储的值或属性取出,返回的是selector对象,且相关的数据值是存储在selector对象的data属性当中,需要调用extract(),extract_first()去除字符串数据。
1.基于终端指令的持久化存储(该种方法只可以将parse方法的返回值存储到本地指定后缀的文件中)
scrapy crawl spidername -o filePath
2.基于管道的持久化存储
- 在爬虫文件中进行数据解析
- 在items.py中定义相关属性(在爬虫文件中解析出几个字段的数据,就在此定义几个属性 )
import scrapy
class DuanziproItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
# Filed()定义好的属性当作一个万能类型的属性
title = scrapy.Field()
content = scrapy.Field()
- 在爬虫文件中将解析到的数据存储封装到Item类型的对象中
- 将Item类型的对象提交给管道
- 在管道文件(pipelins.py)中,接收爬虫文件提交过来的Item对象,且对其进行任意形式的持久化存储
- 在seethings.py 中开启管道机制
- 保存到本地
class DuanziproPipeline:
fp = None
# 重写父类的两个方法
def open_spider(self, spider):
self.fp = open('duanzi.txt', 'w', encoding='utf-8')
print('我是open_spider(),我只会在爬虫开始的时候执行一次!')
def close_spider(self, spider):
print('我是close_spider(),我自会在爬虫结束的时候执行一次!')
self.fp.close()
# 该方法是用来接收item对象的
# 参数item:就是接收到item对象,一次只能接收一个item,说明该方法会被调用多次
def process_item(self, item, spider):
# print(item) # item是一个字典
# 将item存储到文本文件
self.fp.write(item['title'] + '--------' + item['content'] + '\n')
return item
- 保存到mysql
- 首先要导入pymysql(import pymysql)
# 将数据存储到MySQL中
class MysqlPileLine(object):
conn = None
cursor = None
def open_spider(self, spider):
self.conn = pymysql.Connect(host='127.0.0.1', port=3306, user='root', password='******', db='naruto',
charset='utf8')
print(self.conn)
def process_item(self, item, spider):
self.cursor = self.conn.cursor()
sql = 'insert into duanziwang1 values ("%s", "%s")' % (item['title'], item['content'])
# 事务处理
try:
self.cursor.execute(sql)
self.conn.commit()
except Exception as e:
print(e)
self.conn.rollback()
return item
def close_spider(self, spider):
self.cursor.close()
self.conn.close()
补充:一个管道内对应一种形式的持久化存储操作,如果将数据存储到不同的载体中就要使用多个管道类,item不会依次提交给三个管道,爬虫文件中的item只会被提交给优先级最高的那个管道类,所以优先级高的管道类需要在process_item中实现return item,这样一来就将item传递给下一个即将被执行的管道类。