二、、Net_Crawler解析

一、正则匹配

  • 匹配单个字符与数字
----------匹配单个字符与数字---------
.                匹配除换行符以外的任意字符
[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)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,699评论 6 513
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,124评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 167,127评论 0 358
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,342评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,356评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,057评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,654评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,572评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,095评论 1 318
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,205评论 3 339
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,343评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,015评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,704评论 3 332
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,196评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,320评论 1 271
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,690评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,348评论 2 358

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,681评论 18 139
  • 上网原理 1、爬虫概念 爬虫是什麽? 蜘蛛,蛆,代码中,就是写了一段代码,代码的功能从互联网中提取数据 互联网: ...
    riverstation阅读 8,081评论 1 2
  • 20170531 这几天重新拾起了爬虫,算起来有将近5个月不碰python爬虫了。 对照着网上的程序和自己以前写的...
    八神苍月阅读 14,169评论 3 44
  • 我们不生产内容,我们只是互联网的内容搬运工,这是大部分不具备原创能力个人站长的心声。虽然原创能力不够,但是服务目标...
    Frank2288阅读 597评论 0 0
  • 和李光旭结婚前,我在一所高档别墅做保姆,主要就是做做家务带带小孩。 认识李光旭,是别墅女主人热情介绍的,在女主人工...
    瑶鑫宝贝阅读 1,394评论 3 19