Scrapy 探索:使用 Scrapy 爬取自己的 CSDN 博客
来源:互联网 发布:旅游cms系统 编辑:程序博客网 时间:2024/04/29 19:55
一、引言
在学习了 Python 之后,曾经跟随着 《Web Scraping with Python》的作者使用 urllib 和 BeautifulSoup 写过一个爬取自己 CSDN 博客的爬虫,相关博客如下:
Web Scraping with Python: 使用 Python 爬 CSDN 博客
而之后《Web Scraping with Python》的作者用仅仅三四页的篇幅简单介绍了下 Scrapy,而就是这短少的三四页篇幅,打开了我走向 Scrapy 的道路。
而这篇博客,就是用 Scrapy 通过 css 和 xpath 两种书写选择器的方式来实现 CSDN 博客的文章列表信息的爬取。
二、Scrapy 简介
Scrapy 是一个为了爬取网站数据,提取结构性数据而编写的应用框架。其提供了非常丰富实用的特性,能够使得我们编写自己的爬虫程序更加的轻松惬意(比如说 scrapy shell)。
想要了解 Scrapy 的同学可以看看官方文档:
Scrapy中文文档(已经落后于最新文档,并且 demo 也无法成功运行)
Scrapy英文文档(建议看这个)
接下来简单介绍下我们使用
scrapy startproject blog
创建项目之后的文件结构:
参考官方文档,可得知以下文件:
详细的 Scrapy 细节可以参看 Scrapy 的官方文档,建议先看英文版的入门教程,然后高深的内容再看中文版的,这样比较快速一些。
二、选择器(Selectors)的书写
我们想要从博客里面抓取到文章列表中每个文章的以下内容:
- 文章标题(title)
- 阅读量(view)
- 评论量(comments)
于是,我们需要做的,就是使用选择器表达式,在返回的 response 对象中找到这些元素。
这里,我通过 css 和 xpath 两种方式进行了查找。(这里使用 scrapy shell 进行选择器的调试,不了解 scrapy shell 用法的同学可以参看官方文档)
1. css 方式
我们可以通过 Chrome 强大的调试功能,通过 Copy selector 获取某个元素的 css 选择器表达式,然后经过 scrapy shell 调试,写出我们需要的 css 选择器表达式。
# title''.join(article.css('span.link_title a:not(font)::text').extract() ).replace('\r\n', '').strip()# viewarticle.css('span.link_view::text').extract_first().replace('(', '').replace(')', '')# commentarticle.css('span.link_comments::text').extract_first().replace('(', '').replace(')', '')
一般来说,我们可以使用以下的方法来写 css 表达式:
- Chrome Copy selector 获取 css 选择器表达式(以供参考)
- scrapy shell 进行测试
- 如有特殊情况,可以参考 CSS 选择器参考手册
以上三个步骤,基本上已经可以很快速并且准确的写出 css 选择器表达式了。
2. XPath 方式
同样的,我们也可以通过 Chrome 的开发者模式 Copy XPath 获取某个元素的 XPath 表达式,再在 scrapy shell 中进行验证,最后写出我们所需要的最终的 XPath 选择器表达式。
# title''.join(article.xpath('.//span[@class="link_title"]/a/text()' ).extract()).replace('\r\n', '').strip()# viewarticle.xpath('.//span[@class="link_view"]/text()' ).extract_first().replace('(', '').replace(')', '').strip()# commentarticle.xpath('.//span[@class="link_comments"]/text()' ).extract_first().replace('(', '').replace(')', '').strip()
一般来说,我们可以按照以下步骤书写 XPath 选择器表达式:
- Chrome Copy XPath 进行参考
- scrapy shell 中进行测试
- 如有特殊情况,可以参考 XPath 语法
至此,我们已经解决了书写一个爬虫程序最困难的部分了,也就是数据的抓取。
书写选择器表达式确实是一个比较枯燥乏味的工作,但是有了 Chrome 的帮助,再加上强大的 scrapy shell 的即时调试,我们还是可以很轻松惬意的写出来的。
三、自定义 Spider 参数
要想达到可以爬取指定用户的 CSDN 博客的功能,我们需要用户输入的一个用户名参数,比如说我的博客的用户名就是:
u012814856
我们可以简单的使用这个用户名拼凑出任何一个用户的博客页面:
http://blog.csdn.net/u012814856
也就是说,我们需要我们的爬虫程序能够接受一个参数。
幸运的是,Scrapy 支持 Spider 的参数,只需要我们定义一个用于中转存储的 init 函数:
# 默认传入本人的博客名称,也可以使用 Spider 参数指定名称 # scrapy crawl blog-xpath -a user=xxx -o blog-xpath.xml def __init__(self, user='u012814856', *args, **kwargs): super(BlogSpiderXPath, self).__init__(*args, **kwargs) self.start_urls = [ 'http://blog.csdn.net/%s' % user ]
注意,这里我让 BlogSpiderXPath 这个对象构造的时候可以多接收一个 user 参数,这个参数被默认为 u012814856,也就是我自己的博客,我们可以通过以下两种方式运行这个爬虫程序:
# 默认爬取我的博客scrapy crawl blog-xpath# 爬取 xxx 用户的博客scrapy crawl blog-xpath -a user=xxx
相关内容可以查看 Spider arguments
四、代码展示
最后,我们通过只在 blog/spiders 下添加了两个文件 blog-css.py 和 blog-xpath.py 就实现了 css 和 xpath 两种方式爬取博客的功能。
其中,blog-css.py 代码如下:
import scrapyclass BlogSpiderCss(scrapy.Spider): name = 'blog-css' # 默认传入本人的博客名称,也可以使用 Spider 参数指定名称 # scrapy crawl blog-css -a user=xxx -o blog-css.xml def __init__(self, user='u012814856', *args, **kwargs): super(BlogSpiderCss, self).__init__(*args, **kwargs) self.start_urls = [ 'http://blog.csdn.net/%s' % user ] def parse(self, response): for article in response.css('div.article_item'): yield { # 这里要区分该标题是否置顶,如果是置顶的,解析出来就会有两个元素 # ['\r\n ', '\r\n 思考的救赎(二):三消游戏功能完善 \r\n '] # 此时使用 ''.join 即可转换为 str 然后去除空白元素即可 'title': ''.join(article.css('span.link_title a:not(font)::text').extract() ).replace('\r\n', '').strip(), 'view': article.css('span.link_view::text').extract_first().replace('(', '').replace(')', ''), 'comment': article.css('span.link_comments::text').extract_first().replace('(', '').replace(')', ''), } next_page = response.css('#papelist > a:nth-last-child(2)::attr(href)').extract_first() if next_page is not None: yield scrapy.Request(response.urljoin(next_page))
由于 blog-xpath.py 与 blog-css.py 代码逻辑相同,不再赘述,感兴趣的可以下载我的代码观看。
通过在项目根目录下运行:
scrapy crawl blog-xpath -o blog-xpath.xml
我们可以获取到爬取到内容的 blog-xpath.xml 文件信息:
五、总结
学习 Scrapy 的过程,一开始是非常欣喜的,学到了 Selectors 的时候,又会觉得有点懊丧,但坚持下来了之后,又会觉得拨云见日又发现了一个美好的世界。
或许这就是学习的乐趣。
Scrapy 是个非常强大,社区也非常完善的框架,即使作为兴趣来学习,也是一种不错的体验。
本项目仅仅是个非常简单的示例,甚至连 item 和 pipelines 都未使用到。还有更深的内容有待我自己探索了。
想要获取本项目工程文件的同学可以点击这里(其中的 4.blog 文件夹):
wangying2016/LearnScrapy
最后
To be Stronger : )
- Scrapy 探索:使用 Scrapy 爬取自己的 CSDN 博客
- 利用Scrapy爬取自己的CSDN博客
- 使用Scrapy来爬取自己的CSDN文章
- 使用Scrapy来爬取自己的CSDN文章 (2)
- 使用Scrapy来爬取自己的CSDN文章
- scrapy.Selector的使用探索
- Python-爬取自己博客文章的URL
- python爬取自己博客访问量
- Java网络编程(一) - Java网页爬虫 - 爬取自己的CSDN博客标题和阅读数(附源码)
- 使用Scrapy爬取CSDN博客首页文章
- Python3爬虫之二网页解析【爬取自己CSDN博客信息】
- Scrapy研究探索(五)——自动多网页爬取(抓取CSDN某人博客所有文章)
- Scrapy 探索:如何使用 Pycharm 研读 Scrapy 源码
- Scrapy的使用
- scrapy的真实使用
- scrapy 的命令使用
- Scrapy-pipelines的使用
- scrapy爬取博客文章
- Python爬虫——模拟登陆爬取知乎页面
- Python——简单的TCP & UDP 服务器 和 相应的客户端编程
- opencv Mat::release()中断报错
- 可凝儿贵族香氛系列 亮彩保湿沐浴露
- Cmake 自学笔记(linux)(五)
- Scrapy 探索:使用 Scrapy 爬取自己的 CSDN 博客
- JavaScript面向对象思想详解
- java 工资-接口
- 超轻薄笔记本有了新核芯:AMD锐龙移动处理器能否改写市场格局
- 携手京东发力“互联网+手机”,能否成为飞利浦的新起点?
- GTX 1070Ti正式发布!iGame Vulcan X家族再添新成员
- impdp导入时将指定表更名(Remap_table、remap_tablespace、tables在impdp关于只导特定表的注意事项 )
- 连续总结第十六天
- 判断是否完全二叉树