anaconda安装scrapy_Scrapy基础入门(一)
俏咪咪的给自己放了个小长假之后,我白汉三又回来啦。这次要开始慢慢系统学习scrapy了,这个框架真的很厉害,我只是写了个很小的例子,就只花了十行代码就完成了我之前的一篇文章的工作量,而且速度超快,个人认为非常值得学习,它上手简单并且通俗易懂欢迎关注公众号:老白和他的爬虫1.创建一个爬虫在Anaconda+pycharm配置和Scrapy ——环境搭配与一个简单的例子这两篇文章里已经讲述了如何使用a
俏咪咪的给自己放了个小长假之后,我白汉三又回来啦。这次要开始慢慢系统学习scrapy了,这个框架真的很厉害,我只是写了个很小的例子,就只花了十行代码就完成了我之前的一篇文章的工作量,而且速度超快,个人认为非常值得学习,它上手简单并且通俗易懂
欢迎关注公众号:老白和他的爬虫
1.创建一个爬虫
在Anaconda+pycharm配置和Scrapy ——环境搭配与一个简单的例子这两篇文章里已经讲述了如何使用anaconda以及配置anaconda+pycharm环境,没有配置的老铁可以出门右拐,去那里配置一下,anaconda是我一直推荐使用的集成环境,它不需要你再pip很多的包了,直接通过可视化的窗口就可以安装第三方包。通过anaconda自带的spyder编辑器也可以使用scrapy但是需要配合windows下的命令提示符和mac下的终端来操作,相比之下还是pycharm方便一点。
在控制台输入创建一个项目 tutorial
scrapy startproject tutorial
运行成功之后你可以看到你的pycharm的项目列表下有这样的目录
tutorial/scrapy.cfg # deploy configuration filetutorial/# project's Python module, you'll import your code from here__init__.pyitems.py # project items definition filemiddlewares.py # project middlewares filepipelines.py # project pipelines filesettings.py # project settings filespiders/# a directory where you'll later put your spiders__init__.py
在 tutorial/spiders目录下创建一个文件,命名为 quotes_spider.py,代码如下
import scrapyclassQuotesSpider(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'% pagewith open(filename,'wb')as f:f.write(response.body)self.log('Saved file %s'% filename)
简单解释一下这个实例
- scrapy.Spider表示这个继承了这个子类,我们可以使用它的一些方法
- name:表示这个爬虫的名字,必须是独一无二的
- start_requests:返回可重复的Requests.通过自定义输入的起始地址,重复调用parse()解析网页
- parse():定义处理网页的方法
2.运行一个爬虫
对于上述已经创建好的爬虫,在控制台输入以下代码:
scrapy crawl quotes
到这里你要注意这个命令的格式 scrapy是我们使用scrapy框架必须要声明的,前面试过 startproject表示创建一个项目, crawl表示运行一个爬虫,后面会试到更多的命令,这里的 quotes是我们刚在程序里声明的name属性,记住不是它的类的名称也不是文件名。
对于上面我们创建的代码,我们也可以这样简化一下
import scrapyclassQuotesSpider(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'% pagewith open(filename,'wb')as f:f.write(response.body)
这段代码和上面相比,去掉了startrequests方法,只使用starturls存放其实地址。这些初始地址将会被scrapy的默认方法 start_requests()解析,你仔细看代码会惊讶的发现根本就没有调用start_urls这个变量,这是因为parse是scrapy默认的方法。没错,就是这么神奇。
3.学会使用shell
官方的文档告诉我们通过shell命令来学会如何一步一步解析文档,但其实当我们在实际写爬虫的时候,可以利用这个命令来一步一步来修改代码,因为我们需要自己编写爬取信息的具体代码,谁也不敢保证你写的爬取信息的代码一次就成功,如果每一次都通过scrapy crawl * 这样的命令来调试,就太麻烦了,所以shell也是一个很好的调试工具。
输入命令
scrapy shell "http://quotes.toscrape.com/page/1/"
在这之前你可以访问一下网站http://quotes.toscrape.com/page/1/这是scrapy提供的事例网站。运行之后你应该能看到
这里就可以在shell下操作了,使用css选择器来选择相应标签
3.1使用css选择器
获取标签
>>> response.css('title')[<Selector xpath='descendant-or-self::title' data='<title>Quotes to Scrape</title>'>]
获取标签下文本
>>> response.css('title::text').extract()['Quotes to Scrape']
获取标签和文本
>>> response.css('title').extract()['<title>Quotes to Scrape</title>']
上述获取标签所返回的结果都是列表形式的,下面两种方式选择第一个元素,第一种方式能够避免未找到标签而报错
>>> response.css('title::text').extract_first()'Quotes to Scrape'
>>> response.css('title::text')[0].extract()'Quotes to Scrape'
3.2使用xpath
除开css选择器,也可以通过xpath来选择标签。这里有必要解释一下xpath,XPath即为XML路径语言(XML Path Language),它是一种用来确定XML文档中某部分位置的语言,网页HTML也是一种XML。
>>> response.xpath('//title')[<Selector xpath='//title' data='<title>Quotes to Scrape</title>'>]>>> response.xpath('//title/text()').extract_first()'Quotes to Scrape'
xpath非常的强大,scrapy selector就是基于xpath选择器完成的。
3.3实例
选取实例网站http://quotes.toscrape.com,它的html代码大致如下:
<divclass="quote"><spanclass="text">“The world as we have created it is a process of ourthinking. It cannot be changed without changing our thinking.”</span><span>by <smallclass="author">Albert Einstein</small><ahref="/author/Albert-Einstein">(about)</a></span><divclass="tags">Tags:<aclass="tag"href="/tag/change/page/1/">change</a><aclass="tag"href="/tag/deep-thoughts/page/1/">deep-thoughts</a><aclass="tag"href="/tag/thinking/page/1/">thinking</a><aclass="tag"href="/tag/world/page/1/">world</a></div></div>
在pycharm里输入命令行代码
scrapy shell 'http://quotes.toscrape.com'
运行完成后,
>>> response.css("div.quote")
通过结果可以看到,返回了一个符合条件的列表,选择第一个作为我们想要的数据
>>> quote = response.css("div.quote")[0]
所获取的quote也就代表着实例网站中的一个节点
下面这段代码分别获取其中的正文、作者和标签
>>> 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'>>> tags = quote.css("div.tags a.tag::text").extract()>>> tags['change','deep-thoughts','thinking','world']
通过上面这段代码可以了解如何从一个节点中抽取信息,像实例网站中有那么多的节点,只需要设置一个循环就可以全部获取了
>>>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)){'tags':['change','deep-thoughts','thinking','world'],'author':'Albert Einstein','text':'“The world as we have created it is a process of our thinking. It cannot be changed without changing our thinking.”'}{'tags':['abilities','choices'],'author':'J.K. Rowling','text':'“It is our choices, Harry, that show what we truly are, far more than our abilities.”'}... a few more of these, omitted for brevity>>>
4.在scrapy中爬取数据
在第三节里面教会你如何使用shell调试好爬虫代码,现在回到scrapy中去尝试自己的爬虫。到目前为止,除了保存整个HTML文件还没有正式的爬取数据
一个scrapy爬虫一般都是把数据保存在字典中,这里使用yield来保存数据
import scrapyclassQuotesSpider(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(),}
运行代码
scrapy crawl quotes
就可以看到结果了
5.保存你爬取的数据
爬取好的数据可以通过以下的指令来保存
scrapy crawl quotes -o quotes.json
可以看到这比我们之前的代码只多了 -o quotes.json,这个运行的结果都保存在了一个名为 quotes.json的json文件中。但是这个命令面临一个问题,如果你运行两次就会有问题,为了避免这个问题,可以改用以下代码
scrapy crawl quotes -o quotes.jl
命令效果完全相同,不同的是它可以多次运行,每次把新的结果接着之前的文件插入其后。
6.获取翻页链接
在之前的爬虫实战文章里,很重要的一个操作就是如何获取网站的翻页链接,在scrapy中也是一样,在前面的实例代码中,只给了两个链接。通过检查实例网站的翻页按钮,我们可以看到它的代码
<ulclass="pager"><liclass="next"><ahref="/page/2/">Next <spanaria-hidden="true">→</span></a></li></ul>
在shell里这样调试,首先获取a标签
>>> response.css('li.next a').extract_first()'<a href="/page/2/">Next <span aria-hidden="true">→</span></a>'
然后再通过属性 href来获取地址
>>> response.css('li.next a::attr(href)').extract_first()'/page/2/'
下面通过这段代码来实现获取所有翻页链接以及所有网页的信息
import scrapyclassQuotesSpider(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 isnotNone:next_page = response.urljoin(next_page)yield scrapy.Request(next_page, callback=self.parse)
这段代码仔细阅读一下也很好理解,只给定一个初始网页,再获取第一页数据之后,获取翻页链接,此时翻页链接的地址为相对地址,就像 '/page/2/'这样,我们在通过urljoin()方法,使它成为一个绝对地址,然后再利用scrapy对绝对地址发送一个新的request请求。
还有一个捷径直接通过相对地址也可以直接发送request请求,就像这样
import scrapyclassQuotesSpider(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('span small::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 isnotNone:yield response.follow(next_page, callback=self.parse)
试一下同样也可以运行,甚至我们还可以简化
把后面获取翻页链接的代码替换为
for href in response.css('li.next a::attr(href)'):yield response.follow(href, callback=self.parse)
又由于它本身就是a标签我们还可以利用它这个特性再继续简化,把上面的代码再改成
for a in response.css('li.next a'):yield response.follow(a, callback=self.parse)
这样下来,你的代码就简介了很多,最后你也就通过了下面的代码就抓取了一个网站的所有信息。现在是不是一点点发现了scrapy的魅力了,之前我们抓取完全相同的网站华师信管官网,写了大概大几百行代码,现在我们利用了一下scrapy,十行代码搞定
import scrapyclassQuotesSpider(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('span small::text').extract_first(),'tags': quote.css('div.tags a.tag::text').extract(),}for a in response.css('li.next a'):yield response.follow(a, callback=self.parse)
不信你再回去瞅瞅我们第一篇纯手写的爬虫一个简单的爬虫——新闻爬虫
今天就到这了,关注一波吧
更多推荐
所有评论(0)