欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

网页的四种解析方式

程序员文章站 2022-05-15 18:41:23
...

xpath:

/ :从根标签开始
//:从当前标签
星号:通配符,选择所有
//div/book[1]/title: 选择div下面第一个book标签的title元素
//div/bool/title[@lang=“zh”]:选择title属性含有lang且内容为zh的title元素
//div/book/title //book/title //title: 具有相同的效果,因为使用相同路径且最终都指向title
//book/title/@* :将title所有的属性值选择出来
book/title/text() : 将title的内容选择出来,使用内置text()函数
//a[@href=“link1.html” and @id=“place_neighbours__row”] :将a标签href属性为link1.html和id属性为place_neighbours__row选择出来
//a[@href=“link1.html” or @id=“place_neighbours__row”] :将a标签href属性为link1.html或者id属性为place_neighbours__row选择出来
//div/book[lase()]/title/text() :将最后一个book元素选出
//div/book[price>39]/title :将book子标签price数值大于39的选择出来
//li[starts-with(@class,‘item’)] :将class属性前缀是item的li标签选出
//title[contains(@lang,‘eng’)] :将title属性lang含有eng关键字的标签选出

示例:

test_data = """
        <div>
            <ul>
                 <li class="item-0"><a href="link1.html" id="places_neighbours__row">9,596,960first item</a></li>
                 <li class="item-1"><a href="link2.html">second item</a></li>
                 <li class="item-inactive"><a href="link3.html">third item</a></li>
                 <li class="item-1"><a href="link4.html" id="places_neighbours__row">fourth item</a></li>
                 <li class="item-0"><a href="link5.html">fifth item</a></li>
                 <li class="good-0"><a href="link5.html">fifth item</a></li>
             </ul>
             <book>
                    <title lang="aaengbb">Harry Potter</title>
                    <price id="places_neighbours__row">29.99</price>
            </book>
            <book>
                <title lang="zh">Learning XML</title>
                <price>39.95</price>
            </book>
            <book>
                <title>Python</title>
                <price>40</price>
            </book>
         </div>
        """
import lxml.html
html=lxml.html.fromstring(test_data)
html_data=html.xpath("//div/ul/li[2]/a")
for i in html_data:
    print(i.text)

html=lxml.html.fromstring(test_data)
html_data=html.xpath("//book/title/@*")
print(html_data)

html=lxml.html.fromstring(test_data)
html_data=html.xpath("//title[contains(@lang,'eng')]")
print(html_data)
for i in html_data:
    print(i.text)

输出结果:

second item
['aaengbb', 'zh']
[<Element title at 0x1cc7fb03458>]
Harry Potter

如输出所示,因为html_data输出结果是:[<Element title at 0x1cc7fb03458>]
很明显这是一个Element对象,而且在列表中,因此要拿取出来,需要for循环遍历一下,再用.text,一文本形式提取出来

re

python中正则的解析通过re模块完成

compile:生成正则表达式对象

findall:全部匹配,返回匹配到的内容组成的列表,没有返回空列表。
match:从开头进行匹配,匹配到就返回正则结果对象,没有返回
None。
search:从任意位置匹配,功能同上。

匹配规则:

普通字符:简单来说就是一对一的完全匹配。
[]:中间的任意一个字符
[a-z]:a~z之间的任意字符(所有的小写字母)
[a-zA-Z]:匹配所有的字母,多个连续的片段中间不能有任何多余的字符
[^0-9]:匹配除0-9以外的任意字符
. :匹配除’\n’以外的任意字符
\d:数字字符,等价于[0-9]
\D:非数字字符,等价于[^0-9]
\w:匹配字(数字、字母、下划线、汉字)
\W:匹配非字(\w相反的内容)
\s:所有的空白字符(\n、\t、\r、空格)
\S:非空白字符(\s相反的内容)
\b:词边界(开头、结尾、空格、标点等)
\B:非词边界(\b相反的内容)

>*:前面的字符出现任意次
+:至少一次
?:最多一次
{m,n}:m <= 次数 <= n
{m,}:至少m次
{,n}:至多n次
{m}:指定m次

^:以指定的内容开头
$:以指定的内容结束

|:表示或,它拥有最低的优先级
():表示一个整体,可以明确的指定结合性/优先级

a):忽略大小写re.I
b):正则默认是单行匹配,使用 re.M 可以进行多行匹配
c):不使用re.S参数,则只在每一行内进行匹配,如果一行没有,就换下一行重新开始,不会跨行。而使用re.S参数以后,正则表达式会将这个字符串作为一个整体,将“\n”当做一个普通的字符加入到这个字符串中,在整体中进行匹配。

示例:
import re
import requests

response = requests.get('http://example.webscraping.com/places/default/view/Afghanistan-1')
with open('county.html', 'wb')as fp:
    fp.write(response.content)
r = re.compile(r'<tr id="places_population__row">.*?<td class="w2p_fw">(.*?)</td>', re.S)
a = r.findall(response.text)
print(a[0])


string = '''<div>
hello
nihao
hi
</div>'''
s = re.search(r'<div>.*?</div>', string, re.S)

if s:
    print(s.group())


css

#css选择器
#使用lxml解析,lxml常用方法
#选择所有标签*
#选择class=home的标签:a.home
#选择id=ganme的
标签:a#game
#选择
标签的所有字标签span:a>span
#选择
标签的所有后代标签span:a span
#选择title标签属性为home的所有
标签:a[title=home]

import lxml.html
import requests
def parse_lxml(html_str):
    tree=lxml.html.fromstring(html_str)
    td=tree.cssselect('tr#places_languages__row')[0]
    area=td.text_content()#打印标签中所有内容
    return area

result=requests.get('http://example.webscraping.com/places/default/view/China-47')
result=parse_lxml(result.text)
print(result)

输出:
Languages: zh-CN,yue,wuu,dta,ug,za

bs4

from bs4 import BeautifulSoup
import requests
def parse_bs4(html_str):
    soup=BeautifulSoup(html_str,'lxml')
    tr=soup.find(attrs={'id':'places_population__row'})
    area=tr.find(attrs={'class':'w2p_fw'})
    return area.text

result=requests.get('http://example.webscraping.com/places/default/view/China-47')
result=parse_bs4(result.text)
print(result)


输出:
1,330,044,000