函数 - 类 - 模块 - 包 - 框架
新建项目
scrapy startproject Baidu
创建一个新scrapy的爬虫:
scrapy genspider baidu “baidu.com”
创建一个CrawlSpiders的爬虫
scrapy genspider -t crawl baidu baidu.com
执行爬虫
scrapy crawl baidu 或 scrapy runspider baidu.py
可指定文件格式:
scrapy crawl baidu -o baidu.csv
Scrapy 常用的命令和使用流程:
1. 新建项目
scrapy startproject Baidu
2. 定义items.py
的数据字段
3. 新建爬虫
scrapy genspider baidu baidu.com
4. 编写spiders/
里的爬虫代码:
5. 编写pipelines
的管道代码;
6. 通过settings.py 启用相关配置信息
7. 执行爬虫
scrapy runspider baidu.py
或 scrapy crawl baidu
注意:
-
如果有多个爬虫执行,所有的爬虫共享 items.py、pipelines.py、middlewares.py、settings.py 文件;
-
Scrapy
支持基本的文件格式保存方案:json、csv、xml、jl等,执行时 scrapy crawl xxxx -o xxxx.json 输出 -
除非是自定义函数 调用或返回数据,否则在Scrapy的任何组件里 return/yield,都是将数据返回给引擎处理,引擎会自行判断数据类型,并传递给对应的其他组件。
1.发送请求,获取响应 send_request(request)
urllib2、requests
2. 解析响应,提取数据 parse_page(response)
re、xpath、bs4、jsonpath
3. 保存数据 save_data(item)
mysql、redis、mongodb、json、csv、xml
Scrapy 提供了三大对象:
- Request对象
- Response对象
- Item对象
Scrapy 提供了五个核心组件:
Spider
爬虫: -1. 提供第一批url地址, -2. 提供的解析响应的方法(url、item)Scheduler
: -1. 对每个请求做去重处理, -2. 将去重的请求放入请求队列(之后会交给下载器)Downloader
: (并发)发送请求,返回响应Pipeline
: 接收并保存item数据Engine
: 负责调用各个组件和传递数据,保证框架的正常工作。
Scrapy 提供了两个可选的中间件:
- 下载中间件 Downloader Middlewares : 引擎 <-> 下载器 (请求、响应 的预处理)
- 爬虫中间件 Spider Middlewares : 爬虫 <-> 引擎 (请求、item数据、响应)
组件A - 中间件 - 组件B
Scrapy对应下载失败的请求,会有重试操作,总共重试 3 次。
Scrapy的 response 响应主要属性:
response.url # 响应 url地址 非Unicode
response.haeders # 响应报头
response.body # 网页原始编码字符串
response.text # 网页Unicode编码字符串 是Unicode
response.encoding
response.request
response.meta = request.meta
response.xpath("//title/text()") 返回所有匹配结果的表达式列表
再通过 extract() 或 extract_first() 获取字符串内容
extract() : 返回所有结果的字符串列表(没有匹配到数据,返回空列表)
extract_first() : 返回第一个结果的字符串列表(如果没有匹配到数据,返回None)
from lxml import etree
class Response(object):
def __init__(self):
self.url = "xxx"
self.headers = {}
self.body = requests.get().content
self.text = requests.get().text
def xpath(self, rule_str):
html_obj = etree.HTML(self.body)
return html_obj.xpath(rule_str)
response = Response()
result_list = response.xpath("//title/text()")