scrapy框架的简单使用
1 Scrapy框架的命令介绍
Scrapy 命令 分为两种:全局命令
和 项目命令
。
全局命令
:在哪里都能使用。项目命令
:必须在爬虫项目里面才能使用。
全局命令
C:\Users\AOBO>scrapy -h Scrapy 1.2.1 - no active project 使用格式: scrapy <command> [options] [args] 可用的命令: bench 测试本地硬件性能(工作原理:):scrapy bench commands fetch 取URL使用Scrapy下载 genspider 产生新的蜘蛛使用预先定义的模板 runspider 运用单独一个爬虫文件:scrapy runspider abc.py settings 获取设置值 shell 进入交互终端,用于爬虫的调试(如果你不调试,那么就不常用):scrapy shell http://www.baidu.com --nolog(--nolog 不显示日志信息) startproject 创建一个爬虫项目,如:scrapy startproject demo(demo 创建的爬虫项目的名字) version 查看版本:(scrapy version) view 下载一个网页的源代码,并在默认的文本编辑器中打开这个源代码:scrapy view http://www.aobossir.com/ [ more ] 从项目目录运行时可获得更多命令 使用 "scrapy <command> -h" 要查看有关命令的更多信息
项目命令:
D:\BaiduYunDownload\first>scrapy -h Scrapy 1.2.1 - project: first Usage: scrapy <command> [options] [args] Available commands: bench Run quick benchmark test check Check spider contracts commands crawl 运行一个爬虫文件。:scrapy crawl f1 或者 scrapy crawl f1 --nolog edit 使用编辑器打开爬虫文件 (Windows上似乎有问题,Linux上没有问题):scrapy edit f1 fetch Fetch a URL using the Scrapy downloader genspider Generate new spider using pre-defined templates list 列出当前爬虫项目下所有的爬虫文件:scrapy list parse Parse URL (using its spider) and print the results runspider Run a self-contained spider (without creating a project) settings 获取设置值 shell 进入交互终端,用于爬虫的调试(如果你不调试,那么就不常用) startproject 创建一个爬虫项目,如:scrapy startproject demo(demo 创建的爬虫项目的名字) version 查看版本:(scrapy version) view 下载一个网页的源代码,并在默认的文本编辑器中打开这个源代码 Use "scrapy <command> -h" to see more info about a command
注意:Scrapy运行ImportError: No module named win32api错误。请安装:pip install pypiwin32
Scrapy框架的命令使用:
- 查看所有命令
scrapy -h
- 查看帮助信息:
scapy --help
- 查看版本信息:
(venv)ql@ql:~$ scrapy version Scrapy 1.1.2 (venv)ql@ql:~$ (venv)ql@ql:~$ scrapy version -v Scrapy : 1.1.2 lxml : 3.6.4.0 libxml2 : 2.9.4 Twisted : 16.4.0 Python : 2.7.12 (default, Jul 1 2016, 15:12:24) - [GCC 5.4.0 20160609] pyOpenSSL : 16.1.0 (OpenSSL 1.0.2g-fips 1 Mar 2016) Platform : Linux-4.4.0-36-generic-x86_64-with-Ubuntu-16.04-xenial (venv)ql@ql:~$
- 新建一个工程
scrapy startproject spider_name
- 构建爬虫genspider(generator spider)
- 一个工程中可以存在多个spider, 但是名字必须唯一
scrapy genspider name domain #如: #scrapy genspider sohu sohu.org
- 查看当前项目内有多少爬虫
scrapy list
- view使用浏览器打开网页
scrapy view http://www.baidu.com
shell命令, 进入scrpay交互环境
# 进入该url的交互环境 scrapy shell http://www.dmoz.org/Computers/Programming/Languages/Python/Books/
- 之后便进入交互环境,我们主要使用这里面的response命令, 例如可以使用
response.xpath() #括号里直接加xpath路径
- runspider命令用于直接运行创建的爬虫, 并不会运行整个项目
scrapy runspider 爬虫名称
2 Scrapy框架的使用:
- 接下来通过一个简单的项目,完成一遍Scrapy抓取流程。
- 具体流程如下:
- 创建一个scrapy项目:
- 创建一个Spider来抓取站点和处理数据。
- 到过命令行将抓取的抓取内容导出
① 创建项目
- 爬取我爱我家的楼盘信息:
- 网址:https://fang.5i5j.com/bj/loupan/
- 在命令行编写下面命令,创建项目demo
scrapy startproject demo
- 项目目录结构:
demo ├── demo │ ├── __init__.py │ ├── __pycache__ │ ├── items.py # Items的定义,定义抓取的数据结构 │ ├── middlewares.py # 定义Spider和DownLoader的Middlewares中间件实现。 │ ├── pipelines.py # 它定义Item Pipeline的实现,即定义数据管道 │ ├── settings.py # 它定义项目的全局配置 │ └── spiders # 其中包含一个个Spider的实现,每个Spider都有一个文件 │ ├── __init__.py │ └── __pycache__ └── scrapy.cfg #Scrapy部署时的配置文件,定义了配置文件路径、部署相关信息等内容
② 进入demo项目目录,创建爬虫spider类文件
- 执行genspider命令,第一个参数是Spider的名称,第二个参数是网站域名。
scrapy genspider fang fang.5i5j.com $ tree ├── demo │ ├── __init__.py │ ├── __pycache__ │ │ ├── __init__.cpython-36.pyc │ │ └── settings.cpython-36.pyc │ ├── items.py │ ├── middlewares.py │ ├── pipelines.py │ ├── settings.py │ └── spiders │ ├── __init__.py │ ├── __pycache__ │ │ └── __init__.cpython-36.pyc │ └── fang.py #在spiders目录下有了一个爬虫类文件fang.py └── scrapy.cfg # fang.py的文件代码如下: # -*- coding: utf-8 -*- import scrapy class FangSpider(scrapy.Spider): name = 'fang' allowed_domains = ['fang.5i5j.com'] start_urls = ['http://fang.5i5j.com/'] def parse(self, response): pass
- Spider是自己定义的类,Scrapy用它来从网页中抓取内容,并解析抓取结果。
- 此类继承Scrapy提供的Spider类scrapy.Spider,类中有三个属性:name、allowed_domains、start_urls和方法parse。
- name:是每个项目唯一名字,用于区分不同Spider。
- allowed_domains: 它是允许爬取的域名,如果初始或后续的请求链接不是这个域名,则请求链接会被过滤掉
- start_urls:它包含了Spider在启动时爬取的URL列表,初始请求是由它来定义的。
- parse方法:调用start_urls链接请求下载执行后则调用parse方法,并将结果传入此方法。
③ 创建Item
- Item是保存爬取数据的容器,它的使用方法和字典类型,但相比字典多了些保护机制。
- 创建Item需要继承scrapy.Item类,并且定义类型为scrapy.Field的字段:(标题、地址、开盘时间、浏览次数、单价)
- 具体代码如下:
import scrapy class FangItem(scrapy.Item): # define the fields for your item here like: title = scrapy.Field() address = scrapy.Field() time = scrapy.Field() clicks = scrapy.Field() price = scrapy.Field() #pass
④ 解析Response
- 在fang.py文件中,parse()方法的参数response是start_urls里面的链接爬取后的结果。
- 提取的方式可以是CSS选择器、XPath选择器或者是re正则表达式。
# -*- coding: utf-8 -*- import scrapy from demo.items import FangItem class FangSpider(scrapy.Spider): name = 'fang' allowed_domains = ['fang.5i5j.com'] #start_urls = ['http://fang.5i5j.com/'] start_urls = ['https://fang.5i5j.com/bj/loupan/'] def parse(self, response): hlist = response.css("div.houseList_list") for vo in hlist: item = FangItem() item['title'] = vo.css("h3.fontS20 a::text").extract_first() item['address'] = vo.css("span.addressName::text").extract_first() item['time'] = vo.re("<span>(.*?)开盘</span>")[0] item['clicks'] = vo.re("<span><i>([0-9]+)</i>浏览</span>")[0] item['price'] = vo.css("i.fontS24::text").extract_first() #print(item) yield item
⑤、使用Item Pipeline
- Item Pipeline为项目管道,当Item生产后,他会自动被送到Item Pipeline进行处理:
- 我们常用Item Pipeline来做如下操作:
- 清理HTML数据
- 验证抓取数据,检查抓取字段
- 查重并丢弃重复内容
- 将爬取结果保存到数据库里。
class DemoPipeline(object): def process_item(self, item, spider): print(item) return item
- 进入配置settings中开启Item Pipelines的使用
⑥、运行:
- 执行如下命令来启用数据爬取
scrapy crawl fang
- 将结果保存到文件中: 格式:json、csv、xml、pickle、marshal等
scrapy crawl fang -o fangs.json scrapy crawl fang -o fangs.csv scrapy crawl fang -o fangs.xml scrapy crawl fang -o fangs.pickle scrapy crawl fang -o fangs.marshal
2.3 Scrapy框架中的POST提交:
- 在Scrapy框架中默认都是GET的提交方式,但是我们可以使用
FormRequest
来完成POST提交,并可以携带参数。 - 如下案例为有道词典的翻译信息爬取案例,网址:
http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule
- 首先创建一个
youdao
有道的爬虫文件:
scrapy genspider youdao fanyi.youdao.com
- 编写爬虫文件,注意返回的是json格式,具体代码如下:
# -*- coding: utf-8 -*- import scrapy,json class YoudaoSpider(scrapy.Spider): name = 'youdao' allowed_domains = ['fanyi.youdao.com'] #start_urls = ['http://fanyi.youdao.com'] def start_requests(self): url = 'http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule' keyword = input("请输入要翻译的单词:") data = {'i':keyword,'doctype': 'json',} # FormRequest 是Scrapy发送POST请求的方法 yield scrapy.FormRequest( url = url, formdata = data, callback = self.parse ) def parse(self, response): res = json.loads(response.body) print(res['translateResult'][0][0]['tgt']) input("按任意键继续")
END
岁月有你 惜惜相处