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

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

你可以在: http://demo.pyspider.org/debug/tutorial_douban_movie 获得完整的代码,和进行测试。

开始之前

由于教程是基于 pyspider 的,你可以安装一个 pyspider(Quickstart,也可以直接使用 pyspider 的 demo 环境: http://demo.pyspider.org/

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

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

所以,爬网页实际上就是:

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

选取一个开始网址

既然我们要爬所有的电影,首先我们需要抓一个电影列表,一个好的列表应该:

  • 包含足够多的电影的 URL
  • 通过翻页,可以遍历到所有的电影
  • 一个按照更新时间排序的列表,可以更快抓到最新更新的电影

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

创建一个项目

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

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

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

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

Tag 列表页

tag 列表页 中,我们需要提取出所有的 电影列表页 的 URL。你可能已经发现了,sample handler 已经提取了非常多大的 URL,所有,一种可行的提取列表页 URL 的方法就是用正则从中过滤出来:

  1. import re
  2. ...
  3. @config(age=10 * 24 * 60 * 60)
  4. def index_page(self, response):
  5. for each in response.doc('a[href^="http"]').items():
  6. if re.match("http://movie.douban.com/tag/\w+", each.attr.href, re.U):
  7. 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选择器 表达式的元素会被高亮。表达式会被插入到 python 代码当前光标位置。创建下面的代码,将光标停留在单引号中间:

  1. def list_page(self, response):
  2. for each in response.doc('').items():

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

  1. def list_page(self, response):
  2. 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():
  3. self.crawl(each.attr.href, callback=self.detail_page)
  4. # 翻页
  5. for each in response.doc('HTML>BODY>DIV#wrapper>DIV#content>DIV.grid-16-8.clearfix>DIV.article>DIV.paginator>A').items():
  6. self.crawl(each.attr.href, callback=self.list_page)
  • 翻页是一个到自己的 callback 回调

电影详情页

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

  1. def detail_page(self, response):
  2. return {
  3. "url": response.url,
  4. "title": response.doc('HTML>BODY>DIV#wrapper>DIV#content>H1>SPAN').text(),
  5. "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(),
  6. "导演": [x.text() for x in response.doc('a[rel="v:directedBy"]').items()],
  7. }

注意,你会发现 css selector helper 并不是总是能提取到合适的 CSS选择器 表达式。你可以在 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 爬虫教程(一):HTML 和 CSS 选择器的更多相关文章

  1. Pyspider爬虫教程

    Pyspider爬虫教程 一.安装 1. 安装pip (1)准备工作 yum install –y make gcc-c++ python-devel libxml2-devel libxslt-de ...

  2. 爬虫入门【11】Pyspider框架入门—使用HTML和CSS选择器下载小说

    开始之前 首先我们要安装好pyspider,可以参考上一篇文章. 从一个web页面抓取信息的过程包括: 1.找到页面上包含的URL信息,这个url包含我们想要的信息 2.通过HTTP来获取页面内容 3 ...

  3. 【网络爬虫入门04】彻底掌握BeautifulSoup的CSS选择器

    [网络爬虫入门04]彻底掌握BeautifulSoup的CSS选择器 广东职业技术学院  欧浩源 2017-10-21 1.引言 目前,除了官方文档之外,市面上及网络详细介绍BeautifulSoup ...

  4. 第三百四十节,Python分布式爬虫打造搜索引擎Scrapy精讲—css选择器

    第三百四十节,Python分布式爬虫打造搜索引擎Scrapy精讲—css选择器 css选择器 1. 2. 3.  ::attr()获取元素属性,css选择器 ::text获取标签文本 举例: extr ...

  5. 十九 Python分布式爬虫打造搜索引擎Scrapy精讲—css选择器

    css选择器 1. 2. 3.  ::attr()获取元素属性,css选择器 ::text获取标签文本 举例: extract_first('')获取过滤后的数据,返回字符串,有一个默认参数,也就是如 ...

  6. 爬虫学习笔记(2)--创建scrapy项目&&css选择器

    一.手动创建scrapy项目---------------- 安装scrapy: pip install -i https://pypi.douban.com/simple/  scrapy    1 ...

  7. IT兄弟连 HTML5教程 CSS3揭秘 CSS选择器1

    要使用CSS对HTML页面中的元素实现一对一.一对多或者多对一的控制,就需要用到CSS选择器.选择器是CSS3中一个重要的内容,使用它可以大幅度地提高开发人员书写或修改样式表的效率.在大型网站中,样式 ...

  8. Python爬虫教程-33-scrapy shell 的使用

    本篇详细介绍 scrapy shell 的使用,也介绍了使用 xpath 进行精确查找 Python爬虫教程-33-scrapy shell 的使用 scrapy shell 的使用 条件:我们需要先 ...

  9. Python爬虫教程-25-数据提取-BeautifulSoup4(三)

    Python爬虫教程-25-数据提取-BeautifulSoup4(三) 本篇介绍 BeautifulSoup 中的 css 选择器 css 选择器 使用 soup.select 返回一个列表 通过标 ...

随机推荐

  1. 二 python并发编程之多进程-重点

    一 multiprocessing模块介绍 python中的多线程无法利用多核优势,如果想要充分地使用多核CPU的资源(os.cpu_count()查看),在python中大部分情况需要使用多进程.P ...

  2. 【PHP】判断变量是否为控

    1. isset功能:判断变量是否被初始化 说明:它并不会判断变量是否为空,并且可以用来判断数组中元素是否被定义过注意:当使用isset来判断数组元素是否被初始化过时,它的效率比array_key_e ...

  3. debug模式开启会做哪些事(源码分析)

    以往开发中不管是django框架下开发还是其它框架下开发, 只知道在开发阶段要开启debug模式, 却一直没有深究它会我们做哪些事, 今天使用tornado时偶然看到源码中写的很清楚,故写下来加深印象 ...

  4. 网络流 EK算法模板。

    这篇博客讲得很好 #include<queue> #include<stdio.h> #include<string.h> using namespace std; ...

  5. MySQL之架构与历史(二)

    多版本并发控制 MySQL的大多数事务型存储引擎实现的都不是简单的行级锁.基于提升并发性能的考虑,它们一般都同时实现了多版本并发控制(MVCC).不仅是MySQL,包括Oracle.PostgreSQ ...

  6. leetcode 【 Copy List with Random Pointer 】 python 实现

    题目: A linked list is given such that each node contains an additional random pointer which could poi ...

  7. day05_09 列表内置方法

    1.0 count(计算元素出现的次数) t = ['to','be','or','not','to','be'].count('to') print(t) #>>>2 2.0 ex ...

  8. LeetCode668马在棋盘上的概率

    已知一个 NxN 的国际象棋棋盘,棋盘的行号和列号都是从 0 开始.即最左上角的格子记为 (0, 0),最右下角的记为 (N-1, N-1). 现有一个 “马”(也译作 “骑士”)位于 (r, c)  ...

  9. linux实用命令-待补充

    - du 查看目录大小 - du -h 带有单位显示目录信息 - df 查看磁盘大小 - df -h 带有单位显示磁盘信息 - netstat 显示网络状态信息 - 清除僵尸进程 ps -eal | ...

  10. nodejs、yarn编译安装

    yarn和npm一样,是nodejs的一个依赖管理工具 1.安装nodejs 如果缺少c++ compiler 会报错 yum install -y gcc gcc-c++ 安装nodejs V8   ...