专栏首页毛利学Python爬虫必备技能之网页解析库:xpath用法和实战

爬虫必备技能之网页解析库:xpath用法和实战

环境配置

1.本文使用的python版本是python3

2.使用到的依赖包如下:

requests scrapy

在安装 scrapy 之前需要先安装 Twisted 地址: https://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted。下载符合自己版本的 Twisted,然后将其放入 python 安装目录中,先使用命令安装 pip install Twisted。安装完之后,scrapy 就很容易安装了,安装命令如下:pip install scrapy

本文要点

1.xpath 基本语法和用法示例

2.使用 xpath 爬取《盗墓笔记》实例

xpath 基本语法

xpath,全称 XML Path Language,即 XML 路径语言,它是一门在 XML 文档中查找信息的语言。 xpath 的选择功能十分强大,它提供了非常简洁明了的路径选择表达式,几乎所有我们想要定位的节点都可以用 xpath 来选择。首先我们来看下 xpath 的基本语法。

在这里列出了xpath的常用匹配规则,例如 / 代表选取直接子节点,// 代表选择所有子孙节点,. 代表选取当前节点,.. 代表选取当前节点的父节点,@ 则是加了属性的限定,选取匹配属性的特定节点。

xpath 用法举例

接下来我们以豆瓣电影为例子,来熟悉一下 xpath 基本用法: 打开网页 https://movie.douban.com/top250

豆瓣电影top250 首先需要找到我们所匹配的内容在 html 中的位置。 从图片中可以看到排名第一的电影标题是在标签为 div,class 属性为 *hd中的 a 标签中所有的 span 标签里面! 然后我们需要一级一级往上面找,因为这个层级太深了,有时候会匹配不到我们所需要的内容。 我们最开始匹配的标签要满足它的所有特征加起来是唯一的。 很容易看到属性为 article 正是我们所需要的标签!因为找不到第二个 div 标签且class 属性为 article 的标签! 因为是文本内容,所以要用 text(),获取电影标题语法如下 :

html.xpath(".//div[@class='article']/ol/li[1]//div[@class='hd']/a//span[1]/text()")

同理,我们获取电影详情链接的语法,因为是属性,所以要用 @属性值

html.xpath(".//div[@class='article']/ol/li[1]//div[@class='hd']/a/@href")

我们可以将其加入到爬虫代码中,效果如下:

豆瓣电影爬虫

使用 xpath 爬取盗墓笔记

目标地址: 盗墓笔记全篇 http://seputu.com/

总体思路:

1.分析网页结构,取出我们需要的标题,以及下一步需要用到的链接

2.根据章节的链接地址,再爬取出章节小说

首先分析我们需要爬取的内容,在网页中的位置。

经过上面的讲解,相信大家很容易就可以写出 xpath 的语法。因为我们是要爬取所有小说内容,所以我们要循环所有 li 标签里面的内容!

html.xpath(".//div[@class='box']/ul//li")

遍历这个列表,取出我们所需要的章节,详细链接

li_list = selector.xpath(".//div[@class='box']/ul//li")
    for text in li_list:
        title = text.xpath("./a/text()").extract_first('')
        href = text.xpath('./a/@href').extract_first('')

接下来,从详情链接中取出小说内容,即完成了这个小爬虫!

p_list = selector.xpath(".//div[@class='content-body']//p")
    for data in p_list:
        content += data.xpath("./text()").extract_first('')

最重要的分析部分完成了,接下来主要就是将所有的内容放入代码中,然后保存到本地就完成了。

最终爬虫代码如下:

# coding: utf-8
from scrapy import Selector
import requests


class KeyEnum(object):
    TITLE = "title"
    CONTENT = "content"
    HREF = "href"


class NovelSpider(KeyEnum):

    def __init__(self):
        self.headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
                          "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36"
        }

    def spider(self):
        url = 'http://seputu.com/'
        response = requests.get(url, headers=self.headers)
        selector = Selector(text=response.content)
        data_list = []
        li_list = selector.xpath(".//div[@class='box']/ul//li")  # 章节列表
        for text in li_list:
            title = text.xpath("./a/text()").extract_first('')  # 标题
            href = text.xpath('./a/@href').extract_first('')  # 链接
            content = self._content_spider(href)  # 详情页面爬虫
            data_list.append(
                {
                    KeyEnum.HREF: href,
                    KeyEnum.TITLE: title,
                    KeyEnum.CONTENT: content,
                }
            )

        return data_list

    def _content_spider(self, url):
        content = ''

        for _ in range(5):  # 因为没用代理,如果失败,再重试5次
            if url:  # 加个url是否为空的判断
                response = requests.get(url, headers=self.headers)
                if response.status_code != 200:
                    continue
                selector = Selector(text=response.content)

                p_list = selector.xpath(".//div[@class='content-body']//p")
                for data in p_list:
                    content += data.xpath("./text()").extract_first('')

            return content

    def main(self):
        data_list = self.spider()
        for i in data_list:
            with open('盗墓笔记.txt', 'a', encoding='utf-8')as f:
                f.write(i['content'])


if __name__ == '__main__':
    spider = NovelSpider()
    spider.main()

本文分享自微信公众号 - 毛利学Python(sen13717378202)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-07-15

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Android 基础动画之 scale 渐变缩放

    和尚最近在学习 ViewPager 的小动画,说来惭愧,工作这么久了一直没有认真了解过动画这部分,今天特意学习一下 Android 的基本动画。

    阿策
  • 初识 RxPermissions

    和尚曾经在面试 Demo 中处理过权限方面的问题,当时的权限判断都是自己来处理的,不够灵活方便,封装的还远远不够,这次和尚初步尝试一下 RxPerm...

    阿策
  • 前端关键技术点杂烩,这些你必须知道

    这里总结一下 WEB 前端面试的常见问题,同时这些问题也是对一些基础的技术概念和思想的理解。对这些基本知识的掌握程度和深度决定了你的技术层级。高级工程师是必须掌...

    用户5997198
  • Android 基础动画之 alpha 透明度 / translate 平移 / rotate 旋转

    和尚最近在学习 Android 基本动画,前两天整理了一下相对复杂的 Android 基础动画之 scale 渐变缩放,今天继续学习整理其他三种基本...

    阿策
  • springCloud当中Eureca消费者Consumer的部署

    3.消费者的部署: 做个普通的maven project,quickstart archetype。改成jdk.8。过去我们都是: @Service publ...

    马克java社区
  • Spring常用注解大全,收藏一波!!!

    @Configuration 声明当前类为配置类,相当于xml形式的Spring配置(类上)

    程序员追风
  • 什么是AJAX?

    通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。

    公众号php_pachong
  • 【Flutter 专题】 05 图解修改应用名称及图标

    和尚有个臭毛病就是新建的项目都会优先更改一下项目名称,按照自己喜欢的名字定义,当然包括 Logo 也修改一下。刚接触 Flutter,语法都还没有了...

    阿策
  • Android Kotlin/Java 动态设置 shape/drawable 等状态效果

    和尚我最近遇到一个小需求,程序里面有个别页面,需要动态的调整某个页面的样式,包括一键变灰等效果。 以前页面是用 shape 和 draw...

    阿策
  • Android Java 动态修改 CheckBox 样式

    和尚我一直在处理动态配置页面颜色方面的工作,包括各布局,各控件等,而和尚我却在最常用最基本的 CheckBox 选项框这个控件却栽了跟头,折腾了好久...

    阿策

扫码关注云+社区

领取腾讯云代金券