首页 黑客接单正文

人人都会数据采集- Scrapy 爬虫框架入门

言必称“大数据”“人工智能”在这个时代,数据分析和挖掘逐渐成为互联网从业者必备的技能。本文介绍了使用轻量级爬虫框架 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.com
  • pip 将从豆瓣网的软件源下载并安装 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:Spideropened
  • 2017-09-0407:46:55[scrapy.core.engine]DEBUG:Crawled(200)
  • <GEThttps://www.cnblogs.com/cate/mysql/>(referer:None)
  • 获得的响应将保存在 response 物体中。status 属性表示 HTTP 响应状态,正常情况为 200。

  • >>>printresponse.status
  • 200
  • text 属性表示返回的内容数据,可以从这些数据中分析所需的内容。

  • >>>printresponse.text
  • u'<!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)
  • 20
  • response 的 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_title
  • Mysql表的操作和索引操作
  • 然后以类似的方式提取文章摘要:

  • >>>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_date
  • 2017-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-*-
  • importscrapy
  • importsys
  • reload(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=None
  • self.page_index =1
  • ifself.page_index<=20:
  • next_page_url="https://www.cnblogs.com/cate/mysql/"    str(self.page_index)
  • else:
  • next_page_url=None
  • ifnext_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.html
  • classCnblogsScrapyPipeline(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)联系原作者

    戳这里,看作者更好的文章

       
    版权声明

    本文仅代表作者观点,不代表本站立场。
    本文系作者授权发表,未经许可,不得转载。