网页解析 lxml 库–实战

网页解析 lxml 库–实战本节课我们又学习了爬虫的一个新的网页解析库 lxml 从网页中快速解析出想要的目标元素 熟练掌握解析库的使用技巧是必须的基础 爬虫的范围非常的广 爬虫的入门门槛很低 但是要修炼到更高的阶段 道路

大家好,欢迎来到IT知识分享网。

lxml库使用流程

pip install lxml

lxm| 库提供了一个 etree 模块,该模块专门用来解析 HTML/XML 文档,下面来介绍一下 lxml 库的使用流程,主要有 3个步骤:

1、导入模块

from lxml import etree

2、创建解析对象

调用 etree 模块的 HTML() 方法来创建 HTML 解析对象。如下所示!

parse_html = etree.HTML(html)

HTML() 方法能够将 HTML 标签字符串解析为 HTML 文件,该方法可以自动修正 HTML 文本。示例如

from lxml import etree
html_str = '''
<div>
    <ul>
        <li class="item1"><a href="link1.html">Python</a></li>
        <li class="item2"><a href="link2.html">Java</a></li>
        <li class="site1"><a href="www.youbafu.com">跟有霸夫学编程</a>
        <li class="site2"><a href="www.baidu.com">百度</a></li>
        <li class="site3"><a href="www.jd.com">京东</a></li>
    </ul>
</div>'''
html = etree.HTML(html_str)
result = etree.tostring() #将标签元素转换为字符串输出,注意:result为字节类型
print(result.decode('utf-8'))

输出结果如下:

<html><body><div>
    <ul>
        <li class="item1"><a href="link1.html">Python</a></li>
        <li class="item2"><a href="link2.html">Java</a></li>
        <li class="site1"><a href="www.youbafu.com">&#36319;&#26377;&#38712;&#22827;&#23398;&#32534;&#31243;</a>
        </li><li class="site2"><a href="www.baidu.com">&#30334;&#24230;</a></li>
        <li class="site3"><a href="www.jd.com">&#20140;&#19996;</a></li>
    </ul>
</div></body></html>

上述 HTML 字符串存在缺少标签的情况,比如“(语言中文网“缺少一个 闭合标签,当使用了 HTMLO)方法后,会将其自动转换为符合规范的 HTML 文档格式。

3、调用xpath表达式

最后使用第二步创建的解析对象调用 xpath() 方法,完成数据的提取,如下所示:

r_list = parse_html.xpath(‘xpath表达式’)

lxml库提取数据

下面通过一段 HTML 代码实例演示如何使用 lxml 库提取想要的数据。HTML 代码如下所示:

<div class="wrapper"><a href="www.youbafu.com/" id="site">网站类别</a> <ul id="sitename"> <li><a href="http://www.youbafu.com/" title="有霸夫">编程</a></li> <li><a href="http://world.sina.com/" title="新浪娱乐">微博</a></li> <li><a href="http://www.baidu.com" title="百度">百度贴吧</a></li> <li><a href="http://www.taobao.com" title="淘宝">天猫淘宝</a></li> <li><a href="http://www.jd.com/" title="京东">京东购物</a></li> <li><a href="http://www.360.com" title="360科技">安全卫士</a></li> <li><a href="http://www.bytesjump.com/" title=字节">视频娱乐</a></li> <li><a href="http://bzhan.com/" title="b站">年轻娱乐</a></li> <li><a href="http://hao123.com/" title="浏览器">搜索引擎</a></li> </ul> </div>

提取所有a标签的文本

from lxml import etree
# 创建解析对象
parse_html = etree.HTML(html) # 书写xpath表达式,提取文本最终使用text()
xpath_bds = '//a/text()' # 提取文本数据,以列表形式输出
r_list = parse_html.xpath(xpath_bds) # 打印数据列表
print(r_list)

输出结果:

获取所有href的属性值

这里接上面的代码,不同的地方就是xpath的表达式不一样。

xpath_bds = '//a/@href' # 书写xpath表达式,提取文本最终使用text()
r_list = parse_html.xpath(xpath_bds) # 提取文本数据,以列表形式输出
print(r_list) # 打印数据列表

输出结果:

匹配指定内容

输出结果:

[‘http://www.youbafu.com/’]

XPath入门

在编写爬虫程序的过程中提取信息是非常重要的环节,但是有时使用正则表达式无法匹配到想要的信息,或者书写起来非常麻烦,此时就需要用另外一种数据解析方法,也就是本节要学习的 XPath表达式。

XPath表达式

XPath节点

XPath提供了多种类型的节点,常用的节点有:元素、属性、文本、注释以及文档节点。如下所示:

上面的 XML 文档中的节点例子:

节点关系

XML 文档的节点关系和 HTML 文档相似,同样有父、子、同代、先辈、后代节点。如下所示:

上述示例分析后,会得到如下结果:

XPath基本语法

1) 基本语法使用

XPath使用路径表达式在文档中选取节点,下表列出了常用的表达式规则:

网页解析 lxml 库--实战

下面以下述代码为例讲解 XPath表达式的基本应用,代码如下所示:

路径表达式以及相应的匹配内容如下

注意:当需要查找某个特定的节点或者选取节点中包含的指定值时需要使用[]方括号。如下所示

2)XPath通配符

XPath表达式的通配符可以用来选取未知的节点元素,基本语法如下:

网页解析 lxml 库--实战

示例如下:

3)多路径匹配

多个 XPath路径表达式可以同时使用,其语法如下:

网页解析 lxml 库--实战

网页解析 lxml 库--实战

XPath内建函数

XPath提供 100 多个内建函数,这些函数给我们提供了很多便利,比如实现文本匹配、模糊匹配、以及位置匹配等,下面介绍几个常用的内建函数。

网页解析 lxml 库--实战

lxml库实战

确定信息元素结构

网页解析 lxml 库--实战

基准表达式

xpath_bds = ‘//ol[@class=”grid_view”]/li’

输出结果:

我们可以将基准表达式编写的更加详细一点,可以如下

提取数据表达式

分析上述代码段,写出待抓取信息的 XPath表达式,如下所示

完整程序代码

上述内容介绍了编写程序时用到的 XPath表达式,下面正式编写爬虫程序,代码如下所示:

import json
import pandas as pd
import requests
from lxml import html
import csv

class LxmlDoubanTopMovies(object):
    headers = {
        'Host': 'movie.douban.com',
        'Origin': 'movie.douban.com',
        'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Mobile Safari/537.36',
    }

    def __init__(self):
        self.baseurl = 'https://movie.douban.com/top250'
        self.movies = []

    def start_requests(self, url):
        r = requests.get(url, headers=self.headers)
        return r.content

    def parse(self, source):
        parse_html = html.fromstring(source)
        xpath_bds = '//ol[@class="grid_view"]/li/div/div[@class="info"]'
        movie_list = parse_html.xpath(xpath_bds)

        for movie in movie_list:
            title = movie.xpath('div[@class="hd"]/a/span[@class="title"]/text()')
            other = movie.xpath('div[@class="hd"]/a/span[@class="other"]/text()')
            url = movie.xpath('div[@class="hd"]/a/@href')
            m_info = movie.xpath('div[@class="bd"]/p/text()')
            rate_num = movie.xpath('div[@class="bd"]/div[@class="star"]/span[@class="rating_num"]/text()')
            quote = movie.xpath('div[@class="bd"]/p[@class="quote"]/span/text()')

            movie_dic = {}
            movie_dic["电影名称"] = ''.join(title + other).replace(u'\xa0', ' ')
            movie_dic["url"] = url[0] if url else ""
            movie_dic['导演和演员'] = m_info[0].strip().replace(u'\xa0', ' ').replace(u'\u3000', ' ') if m_info else ""
            mi = m_info[1].strip() if len(m_info) > 1 else ""
            movie_dic['发行时间'] = mi.split('/')[0].strip() if '/' in mi else ""
            movie_dic['地区'] = mi.split('/')[1].strip() if '/' in mi else ""
            movie_dic['类别'] = mi.split('/')[2].strip() if '/' in mi else ""
            movie_dic["评分"] = rate_num[0] if rate_num else ""
            movie_dic["简介"] = quote[0] if quote else ""

            self.movies.append(movie_dic)
            print(movie_dic)

        next_page = parse_html.xpath('//span[@class="next"]/a/@href')
        if next_page:
            next_url = self.baseurl + next_page[0]
            text = self.start_requests(next_url)
            self.parse(text)

    def write_json(self, result):
        s = json.dumps(result, indent=4, ensure_ascii=False)
        with open(r'data/lxml_movies.json', 'w', encoding='utf-8') as f:
            f.write(s)

    def write_csv(self, data):
        with open(r'data/lxml_movies.csv', 'w', encoding='utf-8') as f:
            w = csv.DictWriter(f, fieldnames=data[0].keys())
            w.writeheader()
            w.writerows(data)

    def write_excel(self, data):
        excel_file = pd.DataFrame(data)
        excel_file.to_excel(r'data/lxml_movies.xlsx', sheet_name="豆瓣电影lxml", index=False)

    def start(self):
        text = self.start_requests(self.baseurl)
        self.parse(text)
        self.write_json(self.movies)
        self.write_csv(self.movies)
        self.write_excel(self.movies)

if __name__ == '__main__':
    db_movies = LxmlDoubanTopMovies()
    db_movies.start()

课程总结

本节课我们又学习了爬虫的一个新的网页解析库lxml,从网页中快速解析出想要的目标元素,熟练掌握解析库的使用技巧是必须的基础,爬虫的范围非常的广,爬虫的入门门槛很低,但是要修炼到更高的阶段,道路可不平坦,课程所限不能将爬虫的知识展开细讲,同学们有需要可以在拉拉老师的星球里和老师一起来研讨如何写出自己想要的爬虫。

课后练习

网页解析 lxml 库--实战

参考思路:参考实战案例中的parse()方法,首先定位到电影封面图片列表,遍历每项图片模块,在通过xpath定位图片的链接地址,将链接地址传入download(img_url)中保存图片

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/111199.html

(0)
上一篇 2026-01-26 13:33
下一篇 2026-01-26 14:00

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信