美文网首页
二、、Net_Crawler解析

二、、Net_Crawler解析

作者: 铅笔与旧友 | 来源:发表于2018-10-30 17:55 被阅读0次

一、正则匹配

  • 匹配单个字符与数字
----------匹配单个字符与数字---------
.                匹配除换行符以外的任意字符
[0123456789]     []是字符集合,表示匹配方括号中所包含的任意一个字符
[good]           匹配good中任意一个字符
[a-z]            匹配任意小写字母
[A-Z]            匹配任意大写字母
[0-9]            匹配任意数字,类似[0123456789]
[0-9a-zA-Z]      匹配任意的数字和字母
[0-9a-zA-Z_]     匹配任意的数字、字母和下划线
[^good]          匹配除了good这几个字母以外的所有字符,中括号里的^称为脱字符,表示不匹配集合中的字符
[^0-9]           匹配所有的非数字字符
\d               匹配数字,效果同[0-9]
\D               匹配非数字字符,效果同[^0-9]
\w               匹配数字,字母和下划线,效果同[0-9a-zA-Z_]
\W               匹配非数字,字母和下划线,效果同[^0-9a-zA-Z_]
\s               匹配任意的空白符(空格,回车,换行,制表,换页),效果同[ \r\n\t\f]
\S               匹配任意的非空白符,效果同[^ \f\n\r\t]
  • 匹配边界字符
--------------锚字符(边界字符)-------------

^     行首匹配,和在[]里的^不是一个意思   startswith
$     行尾匹配                          endswith

\A    匹配字符串开始,它和^的区别是,\A只匹配整个字符串的开头,即使在re.M模式下也不会匹配它行的行首
\Z    匹配字符串结束,它和$的区别是,\Z只匹配整个字符串的结束,即使在re.M模式下也不会匹配它行的行尾

\b    匹配一个单词的边界,也就是值单词和空格间的位置   bounds
\B    匹配非单词边界

  • 匹配分组
#匹配分组
#|   :或
#()   :整体
#search:会在字符串中从左向左进行查找,如果找到第一个符合条件的,则停止查找
#正则1|正则2:只要正则1或者正则2中的一个满足,则直接按照这个条件查找
  • 模式修正
re.I:忽略大小写模式【ignorecase】
re.M:视为多行模式【more】
re.S:视为单行模式【single】

二、Xpath解析

在 XPath 中,有七种类型的节点:元素、属性、文本、命名空间、处理指令、注释以及文档(根)节点。XML 文档是被作为节点树来对待的。树的根被称为文档节点或者根节点。

  • test.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>测试页面</title>
</head>
<body>
    <ol>
        <li class="haha pp">醉卧沙场君莫笑,古来征战几人回</li>
        <li class="heihei">两岸猿声啼不住,轻舟已过万重山</li>
        <li id="hehe" class="nene">一骑红尘妃子笑,无人知是荔枝来</li>
        <li class="xixi">停车坐爱枫林晚,霜叶红于二月花</li>
        <li class="lala">商女不知亡国恨,隔江犹唱后庭花</li>
    </ol>
    <div id="pp">
        <div>
            <a href="http://www.baidu.com">李白</a>
        </div>
        <ol>
            <li class="huanghe">君不见黄河之水天上来,奔流到海不复回</li>
            <li id="tata" class="hehe">李白乘舟将欲行,忽闻岸上踏歌声</li>
            <li class="tanshui">桃花潭水深千尺,不及汪伦送我情</li>
        </ol>
        <div class="hh">
            <a href="http://mi.com">雷军</a>
        </div>
        <ol>
            <li class="dudu">are you ok</li>
            <li class="meme">会飞的猪</li>
        </ol>
    </div>
</body>
</html>
  • 运用
from lxml import etree
#用etree把整个html字符串加载出来,生成一颗节点树
html = etree.HTML(r.text)   # r.text是文本类型

# 1、根据树形结构获取目标节点
res = html_tree.xpath('/html/body/ol/li[3]')
res = html_tree.xpath('/html/body/div/div[2]/a')

# 2、查找节点中的内容和属性
res = html_tree.xpath('/html/body/div/ol[1]/li[1]/text()')  # ['君不见黄河之水天上来,奔流到海不复回']
# xpath 语法中节点的属性需要用@符号修饰
res = html_tree.xpath('/html/body/div/div[2]/a/@href') #['http://mi.com']

# 3、定位
#(1)层级定位  '/' 代表节点前面有一层  '//' 代表有若干层
res = html_tree.xpath('//li/text()')  

*** text()只获得当前节点的文本内容***
****string() 会获得当前节点下的子孙节点所有文本***

# (2)属性定位
# 获取页面中有class属性的li的元素
res = html_tree.xpath('//li[@id]')
# 获取所有的class值为hehe的li
res = html_tree.xpath('//li[@class="hehe"]')
# 如果一个节点的某个属性有多个值一定要把这些值写全
res = html_tree.xpath('//li[@class="haha pp"]')

# 4、模糊匹配
# 查找所有class值以h开头的li
res = html_tree.xpath('//li[starts-with(@class,"h")]')
# 查找所有class值中含有a的li
res = html_tree.xpath('//li[contains(@class,"h")]')

# 5、逻辑运算
# 查找所有class值为hehe并且id值为tata的li元素
res = html_tree.xpath('//li[@class="hehe" and @id="tata"]')
# 查找所有class值为hehe或者含有a的元素
res = html_tree.xpath('//li[@class="hehe" or contains(@class,"a")]')

obj = html_tree.xpath("//div[@id='pp']")[0]
#以obj为根节点,继续向内部查找
res = obj.xpath('//li/text()') # 无论以谁为根,以'//'开头都是以html为根节点
res = obj.xpath('.//li/text()')  # 以'.//'开头是以当前节点(obj)开始匹配

三、BS4解析

  • 样本html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>soup测试</title>
</head>
<body>
    <div class="tang">
        <ul>
            <li><a href="http://www.baidu.com" title="出塞"><!--秦时明月汉时关,万里长征人未还,但使龙城飞将在,-->不教胡马度阴山</a></li>
            <li><a href="http://www.163.com" class="taohua">人面不知何处去,桃花依旧笑春风</a></li>
            <li><a href="http://mi.com" id="hong">去年今日此门中,人面桃花相映红</a></li>
            <li><a href="http://qq.com" name="he">故人西辞黄鹤楼,烟花三月下扬州</a></li>
        </ul>
    </div>
    <div id="meng">
        <p class="jiang">
            <span>三国猛将</span>
            <ol>
                <li>关羽</li>
                <li>张飞</li>
                <li>赵云</li>
                <li>马超</li>
                <li>黄忠</li>
            </ol>
            <div class="cao">
                <ul>
                    <li>典韦</li>
                    <li>许褚</li>
                    <li>张辽</li>
                    <li>张郃</li>
                    <li>于禁</li>
                    <li>夏侯惇</li>
                </ul>
            </div>
        </p>
    </div>
</body>
</html>
  • 解析
from bs4 import BeautifulSoup

# 1)、把html字符串初始化成一个BeautifulSoup对象
soup = BeautifulSoup(open("./soup_test.html",encoding='utf-8'),'lxml')

# 参数1,一个htnml字符串 参数2,是一个解析器(bs4没有自己的解析器,如果加入其它的解析器,可以提高其解析效率 )

# 1、根据标签名来查找对象,这类方法返回的是这类标签的第一个
# print(soup.title) #<title>soup测试</title>
# print(soup.li)

#2、获取标签的内容
obj = soup.a
# print(obj.string)  # 获取页面中字符串(包括被注释的内容),string属性如果有多个子节点,无法获取
# print(obj.get_text()) # 获取当前标签中的字符串(包括所有后代标签中的字符串),无法获取注释内容

# 3、获取属性
# print(obj.get('title')) # 用get方法获取属性内容
# print(obj['href'])   # 用字典键值获取
# print(obj.attrs)  # 获取标签的所有属性(得到一个字典)
# print(obj.name)  # 获取标签的名

# 4、获取子节点
# print(soup.body.children)  #<list_iterator object at 0x000002098C3E5EF0>

#获取直接子节点
# for child in soup.body.children:
#     print('------------------')
#     print(child)

print(soup.body.descendants)
# 获取当前节点的所有后代节点
# for i in soup.body.descendants:
#     print('------------------')
#     print(i)

# 5、根据相关函数查找节点
# 1) find函数,返回一个对象
# print(soup.find('a')) #寻找第一个a标签
# print(soup.find('',id='hong'))

# 2)find_all函数,返回的是一个列表
# print(soup.find_all('a'))
# print(soup.find_all(['a','span','li']))
# print(soup.find_all(['a','span','li'],limit = 3))
# print(soup.find_all(['a','span','li'],class='taohua'))

# 3)select函数,根据css选择器来查找
# print(soup.select('.taohua'))
# print(soup.select('.tang ul li')) #派生
# print(soup.select('li#hong'))  # 组合(先查找li标签然后找含有id是hong的li)
# print(soup.select('[name="he"]'))  # 属性选择器

四、jsonpath解析

  • 样本json
{ "store": {
    "book": [ 
      { "category": "reference",
        "author": "李白",
        "title": "Sayings of the Century",
        "price": 8.95
      },
      { "category": "fiction",
        "author": "杜甫",
        "title": "Sword of Honour",
        "price": 12.99
      },
      { "category": "fiction",
        "author": "白居易",
        "title": "Moby Dick",
        "isbn": "0-553-21311-3",
        "price": 8.99
      },
      { "category": "fiction",
        "author": "苏轼",
        "title": "The Lord of the Rings",
        "isbn": "0-395-19395-8",
        "price": 22.99
      }
    ],
    "bicycle": {
      "color": "red",
      "price": 19.95
    }
  }
}
  • 解析
import json
import jsonpath


books  = json.load(open('./book.json','r',encoding='utf-8'))

# print(books['store'])
# print(books['store']['book'])
# print(books['store']['book'][1]['price'])
# 查找所有的book的价格

b = books['store']['book']
# for i in b:
#     print(i['price'])


# 用jsonpath查找
# /html/body/div

# 在jsonpath中$代表根节点、 "." 代表当前节点的子节点, ".." 代表当前节点的后代节点
res = jsonpath.jsonpath(books,"$.store.book[*]")
res = jsonpath.jsonpath(books,"$..author")
res = jsonpath.jsonpath(books,"$..book[:3]")
print(res)

相关文章

网友评论

      本文标题:二、、Net_Crawler解析

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