美文网首页
09-数据提取-xpath和lxml模块

09-数据提取-xpath和lxml模块

作者: Vanna_bot | 来源:发表于2019-03-06 18:37 被阅读0次
    • XPath是在HTML/XML中查找信息的语言
    • lxml模块

    XPath

    xpath节点关系

    每个xml标签都叫做节点,最顶层的节点为根节点
    节点选择工具
    Chrome插件 XPath Helper 密码:337b

    xpath语法

    路径表达式

    表达式 描述
    节点名称 选中该元素
    / 从根节点选取、或者是元素和元素间的过渡
    // 获取任意字节
    . 选取当前节点
    .. 选取当前节点的父节点
    @属性值 选取属性
    text() 选取文本

    查找特定节点

    路径表达式 结果
    节点名称[@属性="值"] 选取该节点属性值的所有节点元素
    /父节点/子节点[1] 选取父节点的第一个子节点
    /父节点/子节点[last()] 选取父节点的倒数第一个子节点
    /父节点/子节点[last()-1] 选取父节点的倒数第二个子节点
    /父节点/子节点[position()>1] 选择父节点下面的子节点,从第二个开始选择
    //节点名称/title[text()='Harry Potter'] 选择所有节点下的title元素,仅仅选择文本为Harry Potter的

    通配符

    路径表达式 结果
    /节点名称/* 选取节点下的所有子元素
    //* 选取文档中的所有元素
    //title[@*] 选取所有带有属性的 title 元素

    选取若干路径
    使用“|”运算符连接路径表达式

    lxml模块

    安装
    pip install lxml
    使用

    • 导入lxml模块的etree库
      from lxml import etree
    • 利用etree.HTML,实例化Element对象
      使用xpath(路径表达式),返回列表
    html = etree.HTML(text) 
    ret_list = html.xpath("xpath字符串")
    

    作业:

    用XPath来做一个简单的爬虫,爬取某个贴吧里的所有帖子,获取每个帖子的标题,连接和帖子中图片

    #coding:utf-8
    import os
    import requests
    from lxml import etree
    
    """
    用XPath来做一个简单的爬虫,爬取某个贴吧里的所有帖子,获取每个帖子的标题,连接和帖子中图片
    """
    
    class TieBa():
    
        def __init__(self):
            self.url = "http://tieba.baidu.com/f?ie=utf-8&kw=python&fr=search"
            self.headers = {
                "User-Agent": "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0) "
            }
    
        def get_data(self, url):
            response = requests.get(url, headers=self.headers)
            return response.content
    
        def parse_data(self, data):
            # 解析:获取每个帖子的标题,连接和帖子中图片
            html = etree.HTML(data)
            dt_list = html.xpath('//ul[@id="thread_list"]/li/div/div/div/div/a')
            data_list = []
            for dt in dt_list:
                temp = {}
                # xpath()返回的是个列表
                temp['title'] = dt.xpath('./text()')[0]
                temp['link'] = 'https://tieba.baidu.com' + dt.xpath('./@href')[0]
                data_list.append(temp)
            # 匹配下一页的链接
            try:
                next_url = 'http:' + html.xpath('//a[text()="下一页>"]/@href')[0]
            except:
                next_url = None
            return data_list, next_url
    
        def image_data(self, data):
            html = etree.HTML(data)
            image_list = html.xpath('//*[contains(@id,"post_content_")]/img/@src')
            return image_list
    
        def download(self, image_list):
            if not os.path.exists('images'):
                os.makedirs('images')
            for image in image_list:
                # os.sep根据所属平台生成分隔符
                filename='images'+os.sep+image.split("/")[-1]
                if "sign" in image:
                    data=self.get_data(image)
                    with open(filename, 'wb') as f:
                        f.write(data)
    
        def run(self):
            # url
            # header
            next_url = self.url
            # 循环
            while True:
                # 发送请求获取响应
                data = self.get_data(next_url)
                # 解析:获取每个帖子的标题,连接
                data_list, next_url = self.parse_data(data)
                print(data_list)
                # 打开每个帖子详情页,解析,获取图片链接,下载
                for data in data_list:
                    tz_url=data['link']
                    tz_data = self.get_data(tz_url)
                    image_list = self.image_data(tz_data)
                    print(image_list)
                    # 保存
                    self.download(image_list)
                # 根据是否有下一页判断是否退出循环
                    if not next_url:
                        break
    
    if __name__ == "__main__":
        baidu = TieBa()
        baidu.run()
    

    相关文章

      网友评论

          本文标题:09-数据提取-xpath和lxml模块

          本文链接:https://www.haomeiwen.com/subject/jgezlqtx.html