P4 【Python爬虫】高性能HTML内容解析

目录

1.HTML基础知识

2.HTML的标签和属性

2.1标签

 2.2属性

2.3HTML的树形结构层级关系 

3.XPath

3.1什么是XPath

3.2XPath语法

3.3标签的选取

 3.4省略属性

 3.5应对XPath的一些特殊情况

4.使用Google Chrome浏览器辅助构造XPath 


1.HTML基础知识

        什么是HTML?HTML就是前面我们所看到的,从网页上爬取得到的网页源代码,是一种结构化的标记语言。HTML可以描述一个网页的结构信息。

        HTML与CSS(Cascading Style Sheets,层叠样式表)、JavaScript一起构成了现代互联网的基石。

2.HTML的标签和属性

2.1标签

        在HTML中,这叫作标签。一个标签可以表示为:

<标签名>

        文本

</标签名>

        1.不加斜杠,表示标签开始;加上斜杠,表示标签结束。

        2.它们中间的部分,就是标签里面的元素。

        3.标签里面可以是另一个标签,也可以是一段文本。

        4.标签可以并列,也可以嵌套。

        一段HTML代码实例:        

 2.2属性

         在真实的HTML代码里面,每个标签除了标签名以外,还有“属性”。

        一个标签可以有0个、1个或者多个属性:

 <标签名 属性1="属性1的值" 属性2="属性2的值">显示在网页上的文本</标签名>

2.3HTML的树形结构层级关系 

         层层嵌套,通过这样的树形结构,爬虫可以轻松地找到我我们想要的准确信息。

3.XPath

3.1什么是XPath

        XPath(XML Path)是一种查询语言,它能在XML(Extensible Markup Language,可扩展标记语言)和HTML的树状结构中寻找结点。

        XPath就是一种根据“地址”来“找人”的语言。 

         与正则表达式相比,用正则表达式来提取信息,经常会出现不明原因的无法提取想要内容的情况。而XPath却不一样,熟练使用XPath以后,构造不同的XPath,所需要花费的时间几乎是一样的,所以用XPath从HTML源代码中提取信息可以大大提高效率。

3.2XPath语法

        使用XPath需要安装第三方库lxml。在PyCharm中直接用packages装就ok。

   XPath的核心思想:写XPath就是写地址。

        通用方法模板:

获取文本://标签1[@属性1="属性值1"]/标签2[@属性2="属性值2"]/..../text()
获取属性值://标签1[@属性1="属性值1"]/标签2[@属性2="属性值2"]/..../@属性n

        其中,[@属性="属性值"]不是必需的。它的作用是帮助过滤相同的标签。在不需要过滤相同标签的情况下可以省略。

3.3标签的选取

        找标签的原理:不需要从头开始找,也不能找混杂了有效/无效信息的标签。

        因此,我们需要“倒着找”。也就是,从需要提取的内容往上找标签,找到一个拥有“标志性属性值”的标签为止。

例如,在2.1中,需要的信息所在的标签为<li class="info">,这个标签的class属性的值为“info”。那能不能用它来定位呢?答案是不能,因为在代码里,虽然需要的内容是使用这个标签包起来的,但是不需要的内容也是使用这个标签包起来的。这就说明这个标签的属性值不够独特,不能称为“拥有标志性属性值的标签”。继续往上找,发现<div class="useful">,这个标签很独特。它的class属性的值“useful”独一无二,而且需要提取的内容又都在这个<div>标签里面。所以这个标签可以称得上是“拥有标志性属性值的标签”,可以从这个标签开始来定位。于是定位的XPath就可以写成:

//div[@class="useful"]/ul/li/text() 

 3.4省略属性

        下列代码片段中,<ul>标签本身就没有属性,则写XPath的时候,其属性可以省略。
标签有属性,但是如果这个标签的所有属性值都相同,则可以省略属性,例如<li class="info">,所有的<li>标签都有一个class属性,值都为info,所以属性可以省略。

 3.5应对XPath的一些特殊情况

github代码链接:

1.HTML中有相同的字符开头

HTML代码:

html1 = '''
<! DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>                     
</head>
<body>
<div id="test-1">需要的内容1</div>        
<div id="test-2">需要的内容2</div>
<div id="testfault">需要的内容3</div> 
<div id="useless">这是我不需要的内容</div>
</body> 
</html>
'''

XPath方法:

selector = lxml.html.fromstring(html1)
content = selector.xpath('//div[starts-with(@id, "test")]/text()')

2.HTML中有属性值包含相同字符

        寻找属性值包含某些字符串的元素时,XPath的写法格式和以某些字符串开头的写法格式是相同的,只不过关键字从“starts-with”变成了“contains”。

        lxml中的XPath不支持直接提取属性值以某些字符串结尾的情况。如果遇到这种情况,建议使用contains代替

HTML代码:

html1 = ''''
<! DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>                     
</head>
<body>
<div id="abc-key-1">需要的内容1</div>        
<div id="123-key-2">需要的内容2</div>
<div id="haha-key-hh">需要的内容3</div> 
<div id="useless">这是我不需要的内容</div>
</body>   
</html>
'''

XPath方法:

selector = lxml.html.fromstring(html1)
content = selector.xpath('//div[contains(@id, "key")]/text()')

3.HTML中先抓大再抓小

        可以先抓取useful标签,再对这个标签进一步执行XPath,获取里面子标签的文字。需要注意的是,在对XPath返回的对象再次执行XPath的时候,子XPath开头不需要添加斜线,直接以标签名开始即可。

HTML代码:

source = '''
<html>
    <head>
        <title>测试</title>
    </head>
    <body>
        <div class="useful">
            <ul>
                <li class="info">我需要的信息1</li>
                <li class="info">我需要的信息2</li>
                <li class="info">我需要的信息3</li>
            </ul>
        </div>
        <div class = "useless">
            <ul>
                <li class = "info">垃圾1</li>
                <li class = "info">垃圾2</li>
            </ul>
        </div>
    </body>
</html>         
'''

XPath方法:

selector = lxml.html.fromstring(source)
useful = selector.xpath('//div[@class = "useful"]')
info_list = useful[0].xpath('ul/li/text()')

useless = selector.xpath('//div[@class = "useless"]')
useless_list = useless[0].xpath('ul/li/text()')

4.HTML中抓取不同标签下的文字

        XPath并不会自动把子标签的文字提取出来。在这种情况下,就需要使用string(.)关键字。

HTML代码:

html1 = '''
<! DOCTYPE html>
<html>  
<head lang="en">      
    <meta charset="UTF-8">      
    <title></title>  
</head>  
<body>      
    <div id="test3">        
        我左青龙,        
        <span id="tiger">            
            右白虎,            
            <ul>上朱雀,                
                <li>下玄武。</li>            
            </ul>            
            老牛在当中,        
        </span>        
        龙头在胸口。      
    </div>  
</body>  
</html>
'''

XPath方法:

selector = lxml.html.fromstring(html1)
data = selector.xpath('//div[@id = "test3"]')[0]
info = data.xpath('string(.)')

4.使用Google Chrome浏览器辅助构造XPath 

        在构造XPath语句的过程中,需要寻找“标志性”的标签。但是如果遇到图5-12这样混乱的源代码,就不能单纯靠眼睛来看了。

        借助Google Chrome浏览器来协助分析网页结构,可以大大提高分析效率。Google Chrome自带的开发者工具可以将网页源代码转换为树状结构,大大提高网页的可读性。

        1.在网页上单击右键,在弹出的快捷菜单中选择“检查”命令。

        2.打开开发者工具。使鼠标指针在开发者窗口中的HTML代码中移动,可以看到页面上不同的地方会高亮,说明当前鼠标指针指向的这个标签,就对应了网页中高亮的这一部分的代码。

        3.除了根据代码找网页位置,还可以根据网页位置找代码。

 

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

张小怪的碗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值