pyspider 爬虫教程(一):HTML 和 CSS 选择器

虽然之前写过 如何抓取WEB页面如何从 WEB 页面中提取信息。可是感受仍是须要一篇 step by step 的教程,否则没有一个整体的认识。不过,没想到这个教程竟然会变成一篇译文,在这个爬虫教程系列文章中,会以实际的例子,由浅入深讨论爬取(抓取和解析)的一些关键问题。css

在 教程一 中,咱们将要爬取的网站是豆瓣电影:http://movie.douban.com/html

你能够在: http://demo.pyspider.org/debug/tutorial_douban_movie 得到完整的代码,和进行测试。前端

开始以前

因为教程是基于 pyspider 的,你能够安装一个 pyspider(Quickstart,也能够直接使用 pyspider 的 demo 环境: http://demo.pyspider.org/python

你还应该至少对万维网是什么有一个简单的认识:程序员

  • 万维网是一个由许多互相连接的超文本页面(如下简称网页)组成的系统。
  • 网页使用网址(URL)定位,并连接彼此
  • 网页使用 HTTP 协议传输
  • 网页使用 HTML 描述外观和语义

因此,爬网页实际上就是:web

  1. 找到包含咱们须要的信息的网址(URL)列表
  2. 经过 HTTP 协议把页面下载回来
  3. 从页面的 HTML 中解析出须要的信息
  4. 找到更多这个的 URL,回到 2 继续

选取一个开始网址

既然咱们要爬全部的电影,首先咱们须要抓一个电影列表,一个好的列表应该:chrome

  • 包含足够多的电影的 URL
  • 经过翻页,能够遍历到全部的电影
  • 一个按照更新时间排序的列表,能够更快抓到最新更新的电影

咱们在 http://movie.douban.com/ 扫了一遍,发现并无一个列表能包含全部电影,只能退而求其次,经过抓取分类下的全部的标签列表页,来遍历全部的电影: http://movie.douban.com/tag/app

建立一个项目

在 pyspider 的 dashboard 的右下角,点击 "Create" 按钮ide

Creating a project

替换 on_start 函数的 self.crawl 的 URL:函数

python@every(minutes=24 * 60)
def on_start(self):
    self.crawl('http://movie.douban.com/tag/', callback=self.index_page)
  • self.crawl 告诉 pyspider 抓取指定页面,而后使用 callback 函数对结果进行解析。
  • @every 修饰器,表示 on_start 天天会执行一次,这样就能抓到最新的电影了。

点击绿色的 run 执行,你会看到 follows 上面有一个红色的 1,切换到 follows 面板,点击绿色的播放按钮:

Run ont step

Tag 列表页

tag 列表页 中,咱们须要提取出全部的 电影列表页 的 URL。你可能已经发现了,sample handler 已经提取了很是多大的 URL,全部,一种可行的提取列表页 URL 的方法就是用正则从中过滤出来:

pythonimport re
...

    @config(age=10 * 24 * 60 * 60)
    def index_page(self, response):
        for each in response.doc('a[href^="http"]').items():
            if re.match("http://movie.douban.com/tag/\w+", each.attr.href, re.U):
                self.crawl(each.attr.href, callback=self.list_page)
  • 因为 电影列表页和 tag列表页长的并不同,在这里新建了一个 callbackself.list_page
  • @config(age=10 * 24 * 60 * 60) 在这表示咱们认为 10 天内页面有效,不会再次进行更新抓取

因为 pyspider 是纯 Python 环境,你可使用 Python 强大的内置库,或者你熟悉的第三方库对页面进行解析。不过更推荐使用 CSS选择器。

电影列表页

再次点击 run 让咱们进入一个电影列表页(list_page)。在这个页面中咱们须要提取:

CSS选择器

CSS选择器,顾名思义,是 CSS 用来定位须要设置样式的元素 所使用的表达式。既然前端程序员都使用 CSS选择器 为页面上的不一样元素设置样式,咱们也能够经过它定位须要的元素。你能够在 CSS 选择器参考手册 这里学习更多的 CSS选择器 语法。

在 pyspider 中,内置了 response.docPyQuery 对象,让你可使用相似 jQuery 的语法操做 DOM 元素。你能够在 PyQuery 的页面上找到完整的文档。

CSS Selector Helper

在 pyspider 中,还内置了一个 CSS Selector Helper,当你点击页面上的元素的时候,能够帮你生成它的 CSS选择器 表达式。你能够点击 Enable CSS selector helper 按钮,而后切换到 web 页面:

css selector helper

开启后,鼠标放在元素上,会被黄色高亮,点击后,全部拥有相同 CSS选择器 表达式的元素会被高亮。表达式会被插入到 python 代码当前光标位置。建立下面的代码,将光标停留在单引号中间:

pythondef list_page(self, response):
    for each in response.doc('').items():

点击一个电影的连接,CSS选择器 表达式将会插入到你的代码中,如此重复,插入翻页的连接:

pythondef list_page(self, response):
    for each in response.doc('HTML>BODY>DIV#wrapper>DIV#content>DIV.grid-16-8.clearfix>DIV.article>DIV>TABLE TR.item>TD>DIV.pl2>A').items():
        self.crawl(each.attr.href, callback=self.detail_page)
    # 翻页
    for each in response.doc('HTML>BODY>DIV#wrapper>DIV#content>DIV.grid-16-8.clearfix>DIV.article>DIV.paginator>A').items():
        self.crawl(each.attr.href, callback=self.list_page)
  • 翻页是一个到本身的 callback 回调

电影详情页

再次点击 run,follow 到详情页。使用 css selector helper 分别添加电影标题,打分和导演:

pythondef detail_page(self, response):
    return {
        "url": response.url,
        "title": response.doc('HTML>BODY>DIV#wrapper>DIV#content>H1>SPAN').text(),
        "rating": response.doc('HTML>BODY>DIV#wrapper>DIV#content>DIV.grid-16-8.clearfix>DIV.article>DIV.indent.clearfix>DIV.subjectwrap.clearfix>DIV#interest_sectl>DIV.rating_wrap.clearbox>P.rating_self.clearfix>STRONG.ll.rating_num').text(),
        "导演": [x.text() for x in response.doc('a[rel="v:directedBy"]').items()],
    }

注意,你会发现 css selector helper 并非老是能提取到合适的 CSS选择器 表达式。你能够在 Chrome Dev Tools 的帮助下,写一个合适的表达式:

Chrome Dev Tools

右键点击须要提取的元素,点击审查元素。你并不须要像自动生成的表达式那样写出全部的祖先节点,只要写出那些能区分你不须要的元素的关键节点的属性就能够了。不过这须要抓取和网页前端的经验。因此,学习抓取的最好方法就是学会这个页面/网站是怎么写的。

你也能够在 Chrome Dev Tools 的 Javascript Console 中,使用 $$(a[rel="v:directedBy"]) 测试 CSS Selector。

开始抓取

  1. 使用 run 单步调试你的代码,对于用一个 callback 最好使用多个页面类型进行测试。而后保存。
  2. 回到 Dashboard,找到你的项目
  3. status 修改成 DEBUGRUNNING
  4. run 按钮

pyspider index page


原文:http://blog.binux.me/2015/01/pyspider-tutorial-level-1-html-and-css-selector/ (样式比原文还好看,闹哪样啊)

相关文章
相关标签/搜索