第一种
终端:pip install Scrapy
但由于Scrapy框架涉及多个模块之间的关联,
可能会与当前系统环境发生冲突而导致安装失败
第二种
1.安装Miniconda, 官方下载地址:https://conda.io/miniconda.html
https://www.anaconda.com/download/success
下载安装当前系统对应版本
安装完毕后,打开“开始”菜单,找到Anaconda Prompt,打开可执行程序,输入:
Conda install -c conda-forge scrapy命令,conda就会自动安装Scrapy以及对应的依赖包。
安装完后,直接命令行输入:Scrapy
如图安装成功。
创建Scrapy项目,执行scrapy startproject tutorial 命令
一、爬
以下是Spider代码,保存在tutorial/spiders/目录下的quotes_spider.py文件中:
import scrapy
class QuotesSpider(scrapy.Spider):
name = "quotes"
def start_requests(self):
urls = [
'http://quotes.toscrape.com/page/1/',
'http://quotes.toscrape.com/page/2/',
]
for url in urls:
yield scrapy.Request(url=url, callback=self.parse)
def parse(self,response):
page = response.url.split("/")[-2]
filename = 'quotes-%s.html' % page
with open(filename, 'wb') as f:
f.write(response.body)
self.log('Saved file %s' % filename)
在tutorial项目的根目录,执行scrapy crawl quotes 命令
(注意)
如果在爬取其他网页的过程中出现[403]错误,可以尝试在setting.py 文件中增加USER_AGENT配置:
USER_AGENT = ‘Mozilla/5.0 (Windows NT6.1;WOW64) AppleWebkit/537.36(KHTML,
Like Gecko) Chrome/55.0.2883.87 Safari/537.36’
二、取
项目根目录执行Scrapy Shell:
scrapy shell “http://quotes.toscrape.com/page/1/”
在shell载入后,获得response回应,存储在本地变量response中。
输入:response.body
看到response的body部分,也就是抓取到页面内容。
输入:Response.headers
来查看header部分信息。
使用XPath选择器
XPath其实是一门在网页中查找特定信息的语言。
XPath表达式例子及对应的含义:
/html/head/title:选择HTML文档中head元素内的title元素。
/html/head/title/text():选择上面提到的title元素的文本。
//td:选择所有的td元素。
//div[@class=”mine”]:选择所有具有class”mine”属性的div元素。
筛选出网页标题(title元素中的内容):
>>> response.xpath('//title')
[
extract()方法将Selector的内容提取出来:
>>> response.xpath('//title').extract()
['
title元素中的文本,使用//title/text()方法获取title元素中的文本:
>>> response.xpath('//title/text()').extract()
['Quotes to Scrape']
返回的是一个列表,这是可以通过下标索引[0]获取文本:
>>> response.xpath('//title/text()')[0].extract()
'Quotes to Scrape'
也可以写成这样:
>>> response.xpath('//title/text()').extract_first()
'Quotes to Scrape'
使用CSS选择器
>>> response.css('title')
[
将其元素提取,使用extract()。
>>> response.css('title').extract()
['
在元素后面加上::text,表示只想从元素中将文本提取出来:
>>> response.css('title::text').extract()
['Quotes to Scrape']
Extract_first()方法仍然适用:
>>> response.css('title::text').extract_first()
'Quotes to Scrape'
提取数据:
打开Scrapy Shell模式一下,找想要的数据:
Scrapy shell “http://quotes.toscrape.com”
得到一个带有HTML元素的quote列表:
>>> quote = response.css("div.quote")[0]
使用刚刚创建的quote对象从中提取title、author和tages:
>>> title = quote.css("span.text::text").extract_first()
>>> title
'“The world as we have created it is a process of our thinking. It cannot be changed without changing our thinking.”'
>>> author =quote.css("small.author::text").extract_first()
>>> author
'Albert Einstein'
由于标签是字符串列表,可以使用.extract()方法直接提取:
>>> tags = quote.css("div.tags a.tag::text").extract()
>>> tags
['change', 'deep-thoughts', 'thinking', 'world']
在找出了如何提取每个关键数据之后,现在可以遍历所有的引号元素,并将它们放
在一起成为一个Python字典:
>>> for quote in response.css("div.quote"):
... 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()
... print(dict(text=text, author=author, tags=tags))
在回调中使用Python的yield关键字。
代码修改如下:
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(),
}
tutorial根目录执行:scrapy crawl quotes命令
三、存储内容:
存储抓取数据的最简单方法是使用Feed导出(Feed exports),使用以下命令:
scrapy crawl quotes -o quotes.json
这将生成一个quotes.json文件,其中包含所有被抓取的项目。
出于历史原因,Scarpy将使用“追加”的方式创建文件,而不是覆盖其内容。也就
是说当运行这个命令第二次的时候,如果没有清空原来的JSON文件,由于附加的关系,
将会得到一个不合法的JSON文件。
还可以使用其他格式,如JOSN Lines:
Scrapy crawl quotes -o quotes.jl
JSON Lines格式有时候很管用,因为它是流式的,可以轻松地添加新的记录到它里面。
因此,即使运行两次以上,也不会出现上述问题。此外,由于每条记录都是单独运行,
因此可以处理大文件,而无须将所有内容都放在内存中。
跟进链接:
首先是提取要关注的网页的连接。检查页面,可以看到有一个链接到Next的标记:
尝试在shell中提取它:
>>> response.css('li.next a').extract_first()
'Next '
这时得到锚(anchor)元素,但我们想要href。为此,Scrapy支持一个CSS扩展,
用类选择属性内容,如下所示:
>>> response.css('li.next a::attr(href)').extract_first()
'/page/2/'
现在爬虫被修改为递归跟进到下一页的链接,并从中提取数据:
import scrapy
class QuotesSpider(scrapy.Spider):
name = "quotes"
start_urls = [
'http://quotes.toscrape.com/page/1/',
]
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(),
}
next_page =response.css('li.next a::attr(href)').extract_first()
if next_page is not None:
next_page = response.urljoin(next_page)
yield scrapy.Request(next_page,callback=self.parse)