下载与安装
pip install scrapy
创建项目
scrapy startproject 项目名称
这里我们指定的项目名称为Spider,执行完创建项目的命令后,得到的提示为:
You can start your first spider with:
cd Spider
scrapy genspider example example.com
然后按照提示,依次来执行这两行命令。
这里,cd命令是切换到当前爬虫的工作目录。
genspider 则是生成一个爬虫,该爬虫的名字为example,要爬取的网站为example.com。
当然,example和example.com 可以根据实际情况进行修改。
执行完生成爬虫的命令后,我们可以看到如下提示:
Created spider 'example' using template 'basic' in module:
Spider.spiders.example
从提示中可以看到,这里使用了‘basic’模板来生成爬虫,当然可以指定别的模板
关于另一个模板-crawl请见https://www.cnblogs.com/ASE265/p/12363843.html
最终,我们得到的这整个项目的框架为:
Spider
spiders
_init_.py
example.py
_init_.py
items.py
middleswares.py
pipelines.py
settings.py
scrapy.cfg
这些文件分别是:
- scrapy.cfg:项目配置的文件
- Spider:该项目的python模块,该文件夹的名字为startproject命令指定的名字
- items.py:项目的item文件
- pipilines.py:项目的管道文件
- settings.py:项目的设置文件
- spiders:放置爬虫代码的文件夹
- spiders/example.py:爬虫文件
example.py文件
不同的模板生成的文件是不一样的,这里的example.py文件对应于‘basic’模板。
# -*- coding: utf-8 -*-
import scrapy
class ExampleSpider(scrapy.Spider):
name = 'example'
allowed_domains = ['example.com']
start_urls = ['http://example.com/']
def parse(self, response):
pass
可以看到,该文件定义了一个爬虫类ExampleSpider,它继承于Spider类,各个属性和方法的定义如下:
- name:爬虫的名字,定义了Scrapy如何定义并初始化spider,非常重要的属性
- allowed_domains:指定允许爬取的域名列表
- start_url:当没有指定特定的URL时,爬虫将从该列表中开始进行爬取 另:在start_url中的url不属于指定URL
- parse函数:则是对请求start_url返回的response对象进行分析,该函数需要用户自定义。
至于怎么根据start_url来发出请求我们实际上并不用关心
事实上,Scrapy是有意对其进行了封装
Spider类有一个start_requests()方法
该方法的默认实现是使用 start_urls 的url生成Request
可对该方法进行重写,但大可不必
Spider类还提供了一个make_requests_from_url(url)方法,
当spider启动爬取并指定了URL时,make_requests_from_url()将被调用来创建Request对象
该方法接受一个URL并返回用于爬取的Request对象,也可以对该方法进行重写
另:在看源码的时候发现该方法已被弃用,以后的版本将不再使用该方法
例子:新浪新闻的简单爬取
这里,假设我们已经对新浪新闻网站进行了分析,并决定爬取新浪新闻里的滚动新闻里的国内新闻版块。
为了不与之前的example搞混,我们根据上述的流程重新创建一个用于爬取新浪新闻的爬虫。
具体实现的功能是爬取共爬取10页的所有新闻链接,然后再根据得到的新闻链接爬取对应的新闻
并将新闻的标题,内容和发布时间等信息保存下来。
因此,在我们的爬虫文件中,设置的参数如下:
name = 'sina'
allowed_domains = ['feed.mix.sina.com.cn','sina.com.cn']
start_urls = ["https://feed.mix.sina.com.cn/api/roll/get?pageid=153&lid=2510&k=&num=50&page={}".format(page) for page in range(10)]
然后,决定我们需要爬取的内容
比如我们需要获得每篇文章的标题,关键字,内容,发布的时间,媒体,标签这些内容
因而需要对items.py文件进行设置,设置内容如下:
import scrapy
class SinaItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
title= scrapy.Field()
keywords = scrapy.Field()
time= scrapy.Field()
media = scrapy.Field()
content = scrapy.Field()
tag= scrapy.Field()
pass
然后,回到我们的爬虫文件,将items.py的内容导入到爬虫文件中
from Sina.items import SinaItem
parse函数的一个参数为:response
它是对start_url请求后获得的一个response对象,就是包含了请求的网页的信息
在这里,parse函数实现为:
在response中依次提取url,并将其抛给parsecontent函数
由parsecontent函数来处理请求该url后获得的response的内容。
def parse(self, response):
result = response.text
data = json.loads(result).get('result').get('data')
for news in data:
url = news.get('url')
yield scrapy.Request(url, callback=self.parsecontents)
parseconten函数的内容为根据请求url后返回的response内容进行提取
另:使用xpath对网页格式的内容提取非常方便,推荐使用
def parsecontents(self,response):
title = response.xpath('//title/text()').extract()[0]
meta = response.xpath('//meta/@content').extract()
keywords = meta[2]
time = meta[10]
media = meta[13]
paragraph = response.xpath('//div[@class="article"]/p/text()').extract()
content = ""
for p in paragraph:
content = content + p
item = SinaItem()
item['title'] = str(title)
item['keywords'] = str(keywords)
item['time'] = str(time)
item['media'] = str(media)
item['content'] = str(content)
item['tag'] = "news"
yield item
爬虫运行
在工作目录下输入命令以启动爬虫
scrapy crawl 爬虫名称
这里输入的命令为:scrapy crawl sina
内容保存
爬虫爬取的内容保存实现在pipelines.py文件,在编写爬虫时,我们最后抛出了item。
这个item最后被传送得到了pipelines.py中
在pipelines.py文件中,我们可以实现将获取的item写入文件或者保存得到MongoDB数据库中。
爬虫结果
爬取得到的内容为:
爬取结束后,scrapy会给出统计信息
代码
具体代码,请见github