Scrapy入门-第一个爬虫项目

Scrapy初体验

实现一个最简单的爬虫项目

前言

千辛万苦安装完Scrapy,当然要马上体验一下啦。详见:Mac安装Scrapy及踩坑经验

本文采用循序渐进的方式,一步步写出一个完整的爬虫,包括

  • 使用Scrapy创建项目
  • 使用Scrapy爬取整个网页
  • 使用Scrapy爬取所需元素
  • 使用Scrapy保存数据到json文件

相当于Scrapy入门教程中的基础篇,如果希望学习Scrapy这个强大的爬虫框架,只要懂一点点Python语法,可以跟着一起来动手了。

创建项目

只需一行命令即可创建名为 tutorial 的Scrapy项目:

1
scrapy startproject tutorial

然后 cd tutorial 进入项目目录,通过 tree tutorial 命令看一下整个项目的结构

1
2
3
4
5
6
7
8
9
10
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,这是创建项目的第一步,然后我们再通过

1
2
cd /tutorial
scrapy genspider QuoteSpider

创建爬虫的模板文件,QuoteSpider就是文件名,在当前目录下生成一个QuoteSpider.py文件

然后我们通过PyCharm打开这个 tutorial 项目

项目结构图:
Snip20180722_6.png

QuoteSpider.py 我们开始编写爬虫代码,其他几个文件都有自己的作用,但是本文暂时不需要用到,所以就不介绍了。

有需要的童鞋可以参考知乎的这篇文章:

Scrapy爬虫框架教程(一)– Scrapy入门

爬取整个网页

修改QuotesSpider.py文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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文件:
Snip20180722_7.png

这就完成了我们最最简单的一个爬虫了,总结一下:

  1. scrapy startproject name 创建项目
  2. scrapy genspider spider_name 创建爬虫文件
  3. 编写代码
  4. scrapy crawl spider_name 运行爬虫

提取所需元素

通过爬取整页,我们掌握了最基本的爬虫,但是实际上,通常我们需要的只是网页中一部分对我们有用的信息,那么就涉及到了元素的过滤和筛选。在Scrapy中,我们可以通过 shell 来获取网页元素。

举个例子:

1
scrapy shell 'http://quotes.toscrape.com/page/1/'

你会看到以下信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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选择器来选择所需的元素。例如:

1
2
>>> 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)
1
2
3
4
5
6
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代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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文件

通过以下命令:

1
scrapy crawl quotes -o quotes.json
  • -o:输出
  • quotes.json:保存的json文件名

最终保存下来的结果:
Snip20180723_9.md.png

总结

就以上的Demo而言,Scrapy这个爬虫框架的上手难度算是比较低的,不需要额外的配置,也没有很复杂的模板,基本达到了开箱即用的效果。而且编写代码的过程中也非常简单。一边阅读官方文档,一边自己操作,花了晚上2个小时的时间就能做出这样的效果,个人还是很满意的(为Scrapy打call~)。至于后面的进阶操作,还需要慢慢实践,不断踩坑总结。一起努力吧!


本文结束啦感谢您的阅读