前言
千辛万苦安装完Scrapy,当然要马上体验一下啦。详见:Mac安装Scrapy及踩坑经验
本文采用循序渐进的方式,一步步写出一个完整的爬虫,包括
- 使用Scrapy创建项目
- 使用Scrapy爬取整个网页
- 使用Scrapy爬取所需元素
- 使用Scrapy保存数据到json文件
相当于Scrapy入门教程中的基础篇,如果希望学习Scrapy这个强大的爬虫框架,只要懂一点点Python语法,可以跟着一起来动手了。
创建项目
只需一行命令即可创建名为 tutorial 的Scrapy项目:
scrapy startproject tutorial
然后 cd tutorial 进入项目目录,通过 tree tutorial 命令看一下整个项目的结构
tutorial/
scrapy.cfg # deploy configuration file
tutorial/ # project's Python module, you'll import your code from here
__init__.py
items.py # project items definition file
middlewares.py # project middlewares file
pipelines.py # project pipelines file
settings.py # project settings file
spiders/ # a directory where you'll later put your spiders
__init__.py
OK,这是创建项目的第一步,然后我们再通过
cd /tutorial
scrapy genspider QuoteSpider
创建爬虫的模板文件,QuoteSpider就是文件名,在当前目录下生成一个QuoteSpider.py文件
然后我们通过PyCharm打开这个 tutorial 项目
项目结构图:
在 QuoteSpider.py 我们开始编写爬虫代码,其他几个文件都有自己的作用,但是本文暂时不需要用到,所以就不介绍了。有需要的童鞋可以参考知乎的这篇文章:Scrapy爬虫框架教程(一)– Scrapy入门
爬取整个网页
修改QuotesSpider.py文件
import scrapy
class QuotesSpider(scrapy.Spider):
name = "quotes"
start_urls = [
'http://quotes.toscrape.com/page/1/',
'http://quotes.toscrape.com/page/2/',
]
def parse(self, response):
page = response.url.split("/")[-2]
filename = 'quotes-%s.html' % page
with open(filename, 'wb') as f:
f.write(response.body)
- name 是爬虫的名字,作为唯一标识不可重复
- parse() 方法进行页面解析,我们这里直接保存为html文件
写完代码,怎么开始运行呢?
终端输入:
scrapy crawl quotes
就能看到当前目录下多了两个html文件:
这就完成了我们最最简单的一个爬虫了,总结一下:
- scrapy startproject name 创建项目
- scrapy genspider spider_name 创建爬虫文件
- 编写代码
- scrapy crawl spider_name 运行爬虫
提取所需元素
通过爬取整页,我们掌握了最基本的爬虫,但是实际上,通常我们需要的只是网页中一部分对我们有用的信息,那么就涉及到了元素的过滤和筛选。在Scrapy中,我们可以通过 shell 来获取网页元素。
举个例子:
scrapy shell 'http://quotes.toscrape.com/page/1/'
你会看到以下信息:
2018-07-22 23:59:05 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://quotes.toscrape.com/page/1/> (referer: None)
[s] Available Scrapy objects:
[s] scrapy scrapy module (contains scrapy.Request, scrapy.Selector, etc)
[s] crawler <scrapy.crawler.Crawler object at 0x103186400>
[s] item {}
[s] request <GET http://quotes.toscrape.com/page/1/>
[s] response <200 http://quotes.toscrape.com/page/1/>
[s] settings <scrapy.settings.Settings object at 0x10400f7f0>
[s] spider <DefaultSpider 'default' at 0x1042f6dd8>
[s] Useful shortcuts:
[s] fetch(url[, redirect=True]) Fetch URL and update local objects (by default, redirects are followed)
[s] fetch(req) Fetch a scrapy.Request and update local objects
[s] shelp() Shell help (print this help)
[s] view(response) View response in a browser
>>>
在这里,我们再通过css选择器来选择所需的元素。例如:
>>> response.css('title::text').extract_first()
'Quotes to Scrape'
- title:网页中的标签,也就是我们所需要的元素
- extrac_first() :相当于返回title中的第一个值,因为css返回的是一个列表
做个试验,我们这样写 response.css(‘title::text’).extract()
输出结果为:[‘Quotes to Scrape’],说明返回值就是一个列表
其他所有元素都能通过这个方式来得到,因此接下来我们通过一个完整的例子来实践一下。
获取所需元素并存到json文件
目标:获取网页的text,author,tags元素,并保存下来
步骤1:获取所需的元素(通过CSS)
for quote in response.css('div.quote'):
yield {
'text': quote.css('span.text::text').extract_first(),
'author': quote.css('small.author::text').extract_first(),
'tags': quote.css('div.tags a.tag::text').extract(),
}
这些标签我们可以从html文件中通过查看源码得到他们的层级关系
步骤2:完整的QuotesSpider.py代码
import scrapy
class QuotesSpider(scrapy.Spider):
name = "quotes"
start_urls = [
'http://quotes.toscrape.com/page/1/',
'http://quotes.toscrape.com/page/2/',
]
def parse(self, response):
for quote in response.css('div.quote'):
yield {
'text': quote.css('span.text::text').extract_first(),
'author': quote.css('small.author::text').extract_first(),
'tags': quote.css('div.tags a.tag::text').extract(),
}
步骤3:保存数据到json文件
通过以下命令:
scrapy crawl quotes -o quotes.json
- -o:输出
- quotes.json:保存的json文件名
最终保存下来的结果:
总结
就以上的Demo而言,Scrapy这个爬虫框架的上手难度算是比较低的,不需要额外的配置,也没有很复杂的模板,基本达到了开箱即用的效果。而且编写代码的过程中也非常简单。一边阅读官方文档,一边自己操作,花了晚上2个小时的时间就能做出这样的效果,个人还是很满意的(为Scrapy打call~)。至于后面的进阶操作,还需要慢慢实践,不断踩坑总结。一起努力吧!