言必称“大数据”“人工智能”在这个时代,数据分析和挖掘逐渐成为互联网从业者必备的技能。本文介绍了使用轻量级爬虫框架 scrapy 数据采集的基本 *** 。
一、scrapy简介
scrapy 是一套 Python 基于 编写的异步爬虫框架Twisted 实现,在 运行Linux/Windows/MacOS 等环境具有速度快、扩展性强、使用方便等特点。即使是新手也能快速掌握和编写所需的爬虫程序。scrapy 可在本地运行或部署到云中(scrapyd)实现真正的生产级数据采集系统。
我们通过一个例子学习如何使用 scrapy 从 *** 上收集数据。“博客园”这是一个技术性的综合信息网站。这次我们的任务是收集这个网站 MySQL 类别
https://www.cnblogs.com/cate/mysql在所有文章的标题、摘要、发布日期和阅读量下,共有四个字段。最终结果是一份包含所有四个字段的文本文件。如图所示:
最终拿到的数据如下所示,每条记录有四行,分别是标题、阅读数量、发布时间、文章摘要:
二、安装scrapy
我们来看看如何安装 scrapy。首先,你的系统必须有 Python 和 pip,这篇文章是最常见的 Python2.7.5以 版为例。pip 是 Python 一般来说, 包管理工具Linux 默认安装在系统中。输入以下命令并执行命令:
sudopipinstallscrapy-ihttp://pypi.douban.com/simple–trusted-host=pypi.douban.compip 将从豆瓣网的软件源下载并安装 scrapy,所有依赖的包都将自动下载和安装。”sudo”这意味着该命令由超级用户执行。所有进度条完成后,如果提示相似”Successfully installed Twisted,scrapy … “,说明安装成功。
三、scrapy交互环境
scrapy 还提供了交互操作的 Shell,方便我们测试分析规则。scrapy 安装成功后,在命令行中输入 scrapy shell 即可启动 scrapy 交互环境。scrapy shell 的提示符是三个大于号码的提示符>>>,表示可以接收命令了。我们先用 fetch() 获取主页内容的 *** :
>>>fetch(“https://www.cnblogs.com/cate/mysql/”)如果屏幕上有以下输出,则表页内容已获得。
2017-09-0407:46:55[scrapy.core.engine]INFO:Spideropened2017-09-0407:46:55[scrapy.core.engine]DEBUG:Crawled(200)<GEThttps://www.cnblogs.com/cate/mysql/>(referer:None)获得的响应将保存在 response 物体中。status 属性表示 HTTP 响应状态,正常情况为 200。
>>>printresponse.status200text 属性表示返回的内容数据,可以从这些数据中分析所需的内容。
>>>printresponse.textu'<!DOCTYPEhtml>\r\n<htmllang=”zh-cn”>\r\n<head>\r\n<metacharset=”utf-8″/>\r\n<metaname=”viewport”content=”width=device-width,initial-scale=1″/>\r\n<metaname=”referrer”content=”always”/>\r\n<title>MySQL–\u7f51\u7ad9\u5206\u7c7b–\u535a\u5ba2\u56ed</title>\r\n<linkrel=”shortcuticon”href=”//common.cnblogs.com/favicon.ico”type=”image/x-icon”/>’可见是一堆很乱的 HTML 代码,不能直观地找到我们需要的数据。此时,我们可以通过浏览器“开发者工具” 获取指定数据DOM 路径。用浏览器打开网页 https://www.cnblogs.com/cate/mysql/ 之后,按 F12 键启动开发者工具,快速定位指定内容。
我们可以看到个字段都在 / body / div(id=”wrapper”) / div(id=”main”) / div(id=”post_list”) / div(class=”post_item”) / div(class=”post_item_body”) / ,每一个”post_item_body”它们都包含一篇文章的标题、摘要、发布日期和阅读量。我们首先得到所有的”post_item_body”,然后从中分析每篇文章的四个字段。
>>>post_item_body=response.xpath(“//div[@id=’wrapper’]/div[@id=’main’]/div[@id=’post_list’]/div[@class=’post_item’]/div[@class=’post_item_body’]”)>>>len(post_item_body)20response 的 xpath *** 可用 xpath 分析器获取 DOM 数据,xpath 语法请参考官网文档。可以看出,我们在主页上获得了所有 20 文章 post_item_body。那么如何提取每篇文章的这四个字段呢?
我们以***以文章为例***个 post_item_body:
>>>first_article=post_item_body[0]标题在 post_item_body 节点下的 h3 / a 中,xpath *** 中text()取当前节点的文字,extract_first() 和 strip() 是 xpath 表达式中的节点提取并过滤掉前后的空格和回车符:
>>>article_title=first_article.xpath(“h3/a/text()”).extract_first().strip()>>>printarticle_titleMysql表的操作和索引操作然后以类似的方式提取文章摘要:
>>>article_summary=first_article.xpath(“p[@class=’post_item_summary’]/text()”).extract_first().strip()>>>printarticle_summary表的操作:1.表的创建:createtableifnotexiststable_name例子:createtableifnotexistsuser(idintauto_increment,unamevarchar(20),addressvarch…在提取 post_item_foot 发现提取了两组内容,***组是空的,第二组是空的。“发布于 XXX”文字。提取第二组内容并过滤掉“发布于”三个字:
>>>post_date=first_article.xpath(“div[@class=’post_item_foot’]/text()”).extract()[1].split(“发布于”)[1].strip()>>>printpost_date2017-09-0318:13***提取阅读量:
>>>article_view=first_article.xpath(“div[@class=’post_item_foot’]/span[@class=’article_view’]/a/text()”).extract_first()>>>printarticle_view阅读(6)很多人认为 xpath *** 里的规则太过复杂。其实只要了解一点 HTML 文件的 DOM 结构,掌握 xpath 的提取规则相对容易。幸运的是, scrapy shell 允许我们反复对 DOM 文件进行尝试解析。实验成功的 xpath 表达式可直接用于项目。
四、创建scrapy项目
scrapy shell 只适用于测试目标网站能否正常收集以及收集后如何分析。当你真正做项目时,你需要从头开始建立一个 scrapy 项目。 输入以下命令退出 scrapy shell 并返回 Linux 命令行:
>>>exit()假设我们的项目名称是 cnblogs_scrapy ,可以通过以下命令创建 scrapy 项目:
scrapystartprojectcnblogs_scrapy以下结构的目录和文件将自动生成:
|–cnblogs_scrapy||–__init__.py||–items.py||–middlewares.py||–pipelines.py||–settings.py|`–spiders|`–__init__.py`–scrapy.cfg五、分析与存储
我们需要改三个地方:
1. 在spiders在目录下建立文件cnblogs_mysql.py
内容如下:
#-*-coding:utf-8-*-importscrapyimportsysreload(sys)sys.setdefaultencoding("utf8")classCnblogsMySQL(scrapy.Spider):#爬虫的名字必须有这个变量name='cnblogs_mysql'page_index=1#初始地址必须有这个变量start_urls=['https://www.cnblogs.com/cate/mysql/' str(page_index),]defparse(self,response):post_items=response.xpath("//div[@id='wrapper']/div[@id='main']/div[@id='post_list']/div[@class='post_item']/div[@class='post_item_body']")forpost_item_bodyinpost_items:yield{'article_title':post_item_body.xpath("h3/a/text()").extract_first().strip(),'article_summary':post_item_body.xpath("p[@class='post_item_summary']/text()").extract_first().strip(),'post_date':post_item_body.xpath("div[@class='post_item_foot']/text()").extract()[1].strip(),'article_view':post_item_body.xpath("div[@class='post_item_foot']/span[@class='article_view']/a/text()").extract_first().strip()}next_page_url=Noneself.page_index =1ifself.page_index<=20:next_page_url="https://www.cnblogs.com/cate/mysql/" str(self.page_index)else:next_page_url=Noneifnext_page_urlisnotNone:yieldscrapy.Request(response.urljoin(next_page_url))这是我们的爬虫, name 和 start_urls 必须存在两个变量。parse *** 的作用是将响应内容分析为我们需要的数据。parse 中的 for 循环是在每页提取 20 文章。分析提取后,通过 yield 把结果扔到 pipeline 储存。
2. 修改pipelines.py内容如下:
#-*-coding:utf-8-*-#Defineyouritempipelineshere##Don'tforgettoaddyourpipelinetotheITEM_PIPELINESsetting#See:http://doc.scrapy.org/en/latest/topics/item-pipeline.htmlclassCnblogsScrapyPipeline(object):defopen_spider(self,spider):self.fp=open("data.list","w")defclose_spider(self,spider):self.fp.close()defprocess_item(self,item,spider):self.fp.write(item["article_title"] "\n")self.fp.write(item["article_view"] "\n")self.fp.write(item["post_date"] "\n")self.fp.write(item["article_summary"] "\n\n")returnitem可见有三种 *** 。这三种 *** 是从基类中继承的。open_spider/close_spider 分别在爬虫启动和结束的时候执行,一般用作初始化及收尾。process_item 每次 spider 数据分析后 yield 在处理分析结果时执行。上面的 pipeline 的功能是将每个记录存储在文件中。当然也可以通过 pipeline 将内容存储在数据库或其他地方。
3. 配置pipeline
只注意这个 pipeline 文件不能工作,需要在配置文件中向 scrapy 声明 pipeline。在同一目录下有一个 settings.py 文件,添加以下内容:
ITEM_PIPELINES={'cnblogs_scrapy.pipelines.CnblogsScrapyPipeline':300,}后面的数字是 pipeline 的权重,如果爬虫有多个 pipeline,各个 pipeline 的执行顺序取决于权重。
修改保存后,退回 cnblogs_scrapy 上层目录,输入以下命令启动爬虫:
scrapycrawlcnblogs_mysql所有处理过的信息都将输出到屏幕上。之后,将在当前目录中生成 data.list 本次收集的所有数据都存储在文件中。
六、翻页
cnblogs_mysql.py 的 parse *** 中有个 next_page_url 变量,一般来说,这个变量的内容应该是当前页面的下一页 URL,该 URL 当然也可以通过分析页面获得。获得下一页URL之后,用 scrapy.Request 发起新的请求。简单来说,本文直接拼接 URL 的形式指定只收集前 20 页的数据。
七、其它
用 scrapy 在发送请求之前,也可以自己构 Request,这样就可以伪装成真实访问,避免被封存。通常修改 User-Agent、随机采集时间,随机 *** IP 等 *** 。scrapy 项目可以直接运行,也可以部署在云端进行批量采集和监控。云端部署需要用到 scrapyd,操作也很简单,必要时可以参考官网文档。
【本文是51CTO专栏机构“岂安科技”请通过微信微信官方账号转载原创文章。(bigsec)联系原作者
戳这里,看作者更好的文章