第二十七篇 网页数据解析三种方法: 正则表达--BeautifulSoup--xpath 满满的干货

心得:
生活不允许自己懈怠自己,革命尚未成功,同志还须努力,有句话说的好,你尽管努力,剩下的交给天意。

我们从网页上抓取的原始数据大多都是html的数据格式,那如何从html中提取想要的字符串,得需要用到今天所介绍得三种方法:

1.正则表达式

爬虫常用正则表达式:a.*?b(.?)c.?d 可以匹配具备a,b,c,d格式得字符串,但不捕获。常用的分组匹配法,当然还有其他方式匹配,详细匹配请参考:
https://blog.csdn.net/qq_45503700/article/details/102692581

正则表达式默认下只会匹配单行,不会去匹配\n,如果想要去匹配多行或者\n符号,有三种方式:
1.re.findall(r’<div class=“bookname”>.?target="_blank">(.?)’,r,re.S)
2.re.findall(r’<div class=“bookname”>.?target="_blank">(.?)’,r,re.DOTALL)
3.re.findall(r’<div class=“bookname”>.?target="_blank">((?:.|\n)?)’,r,re.S),将 . 改为 ?:.|\n

来看一个例子,爬取小说网站的小说名字:

book_name的段落,抓取的网页中书名都是这种格式,所以我们只需要匹配格式,就可以拿到所有的书名。

"""
<div class="bookname">
                            <a href="http://book.zongheng.com/book/893716.html" target="_blank">逆仙狂刀</a>
                        </div>
"""

看代码:

import requests
from lxml import etree
from bs4 import BeautifulSoup
import json
import re

url = 'http://book.zongheng.com/store/c1/c0/b0/u1/p1/v0/s9/t1/u0/i1/ALL.html'
headers={
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36"
    }
r=requests.get(url=url,headers=headers).text
re_text=re.findall(r'<div class="bookname">.*?target="_blank">(.*?)</a>',r,re.S)
#应用了多行匹配的属性和分组匹配就很容易匹配到想要的格式
print(re_text)

结果:

PS C:\Users\TianJian\Desktop\python> & C:/Users/TianJian/AppData/Local/Microsoft/WindowsApps/python.exe c:/Users/TianJian/Desktop/python/数据解析1107/数据练习.py
['命运之魔途', '携天命而来', '弑魔英雄传', '捡个老妖当师父', '万古龙神', '逆仙狂刀', '南无斗战胜佛', '浮生墓', '紫罗道', '山海长恨歌', '星辰倒影', '盾御九州', '苜蓿传', '凭虚御风', '乾
源春秋', '龙鸣狮吼', '星帝诀', '问长生', '时间之主', '光暗龙印', '战魂苍穹', '无量魂诀', '认真修炼是不可能的', '六道问心', '最强雇佣兵', '冰裂星空', '我在人间修仙路', '弑神缥缈录', '海
洋传说之魔法王子', '纨绔圣尊', '我有一座灵药铺', '盖世仙尊', '幻武至尊', '山海神纪之凤皇与光之宝石', '紫薇幻', '空山剑雨', '至尊人生', '绝世阎魔', '九霄神皇', '万世环师', '王霸之气最强
者龙傲天', '命运卡牌锦马超', '太鸿', '破渊', '云顶附身系统', '父爱未迟', '幻世异魔录', '不灭道心', '斥天曲', '随身带个游戏库']
PS C:\Users\TianJian\Desktop\python>

2.BeautifulSoup

BeautifulSoup库作为python特有的数据解析库,使用起来还是特别顺手的,介绍一下常用的几种操作方法。

1 导入库
from bs4 import BeautifulSoup

2.实例化对象
本地文件:
html_text=open("./test.html","r",encoding="utf-8")  
爬取的文本:
html_text=response.text

soup=BeautifulSoup(html.text,"html.parser")

3.数据解析的方法和属性:
-find 返回的是节点对象
    soup.find("div",classname_="value")
    
-find_all 返回的是列表,返回所有符合的标签
    soup.find_all("div",classname_="value")   
    
-select 层级选择器  返回的是列表
    定位:
    soup.select("tang>ul>li>a")  >表示一个层级,定位到a节点
    soup.select("tang.content>ul>li>a") .content 表示tang节点属性为content的节点
    soup.select("tang#123>ul>li>a") #123 表示tang节点ID为123的节点
    
    取值文本数据:
    soup_content.string  获取目标节点下的文本,必须是当前节点的文本,有层级关系取不到
    soup_content.text   获取目标节点下所有的文本内容  
    取标签中的文本:
    soup_content.attrs['href'] 取出目标标签中,href属性的文本
4.持久化存储
with open(path,"w",encoding="utf-8") as f:
    f.write(content)

来看看BeautifulSoup是如何筛选数据的,还是刚刚的小说网站:

import requests
from lxml import etree
from bs4 import BeautifulSoup
import json
import re

url = 'http://book.zongheng.com/store/c1/c0/b0/u1/p1/v0/s9/t1/u0/i1/ALL.html'
headers={
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36"
    }
r=requests.get(url=url,headers=headers).text
soup=BeautifulSoup(r,"html.parser")  #实例化soup
#soup.prettify()  用来美化抓取出的数据格式,层次更清晰
result=soup.select("div.bookname>a") #通过分层定位目标节点,返回的result为一个个节点组成的列表
for i in result:  #通过遍历输出每一个节点对应文本
    print(i.string,end=" ")

结果:

PS C:\Users\TianJian\Desktop\python> & C:/Users/TianJian/AppData/Local/Microsoft/WindowsApps/python.exe c:/Users/TianJian/Desktop/python/数据解析1107/数据练习.py
命运之魔途 携天命而来 弑魔英雄传 捡个老妖当师父 万古龙神 逆仙狂刀 南无斗战胜佛 浮生墓 紫罗道 山海长恨歌 星辰倒影 盾御九州 苜蓿传 凭虚御风 乾源春秋 龙鸣狮吼 星帝诀 问长生 时间之主 光暗
龙印 战魂苍穹 无量魂诀 认真修炼是不可能的 六道问心 最强雇佣兵 冰裂星空 我在人间修仙路 弑神缥缈录 海洋传说之魔法王子 纨绔圣尊 我有一座灵药铺 盖世仙尊 幻武至尊 山海神纪之凤皇与光之宝石
紫薇幻 空山剑雨 至尊人生 绝世阎魔 九霄神皇 万世环师 王霸之气最强者龙傲天 命运卡牌锦马超 太鸿 破渊 云顶附身系统 父爱未迟 幻世异魔录 不灭道心 斥天曲 随身带个游戏库
PS C:\Users\TianJian\Desktop\python>

3.xpath

如果说好用我个人更喜欢用BeautifulSoup库,为啥还要学xpath库,因为xpath库是所有语言通用的库,所以学好之后其他语言也可以使用。还有一点好处是Chrome浏览器可以直接定位出对应节点xpath的语法,所有为了后期更大的发展,建议采用更广法用途的xpath语法。

1 导入库
from lxml import etree

2 实例化etree对象
    本地导入:
    r=etree.parse(filepath)
    
    互联网获取的数据:
    r=etree.HTML(page_text)

3.xpath表达式 (返回的数据格式为列表)
- r.xpath('表达式')
    定位:
    - / 表示从跟节点开始定位
    - // 表示多个层级或者从任意位置开始定位
    - //div[@class="song"]  属性定位 ,一定要记着不光有属性值还有属性名字
    - //div[@class="song"]/p[3]  索引定位,索引是从1开始
    取文本:
    - //p/text()    获取直系的文本
    - //p//text()   获取p节点下的所有内容
    取属性
    - /@attrs  取属性文本

来看看xpath是如何筛选出小说网站书名的:

import requests
from lxml import etree
from bs4 import BeautifulSoup
import json
import re

url = 'http://book.zongheng.com/store/c1/c0/b0/u1/p1/v0/s9/t1/u0/i1/ALL.html'
headers={
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36"
    }
r=requests.get(url=url,headers=headers).text
tree=etree.HTML(r)   #实例化etree对象
name=tree.xpath('//div[@class="bookname"]/a/text()')  #使用xpath语法直接输出节点内容
print(name)

结果:

PS C:\Users\TianJian\Desktop\python> & C:/Users/TianJian/AppData/Local/Microsoft/WindowsApps/python.exe c:/Users/TianJian/Desktop/python/数据解析1107/数据练习.py
['命运之魔途', '携天命而来', '弑魔英雄传', '捡个老妖当师父', '万古龙神', '逆仙狂刀', '南无斗战胜佛', '浮生墓', '紫罗道', '山海长恨歌', '星辰倒影', '盾御九州', '苜蓿传', '凭虚御风', '乾
源春秋', '龙鸣狮吼', '星帝诀', '问长生', '时间之主', '光暗龙印', '战魂苍穹', '无量魂诀', '认真修炼是不可能的', '六道问心', '最强雇佣兵', '冰裂星空', '我在人间修仙路', '弑神缥缈录', '海
洋传说之魔法王子', '纨绔圣尊', '我有一座灵药铺', '盖世仙尊', '幻武至尊', '山海神纪之凤皇与光之宝石', '紫薇幻', '空山剑雨', '至尊人生', '绝世阎魔', '九霄神皇', '万世环师', '王霸之气最强
者龙傲天', '命运卡牌锦马超', '太鸿', '破渊', '云顶附身系统', '父爱未迟', '幻世异魔录', '不灭道心', '斥天曲', '随身带个游戏库']
PS C:\Users\TianJian\Desktop\python>

xpath语法有时匹配的内容不是你想要的字符串,你可以用具体的属性值,来进一步筛选,方法如下:

#原始数据
"""
<div class="bookname">
                            <a href="http://book.zongheng.com/book/893716.html" target="_blank">逆仙狂刀</a>
                        </div>
"""
#用此节点下的具体属性来进一步限定
name=tree.xpath('//div[@class="bookname"]/a[contains(@target,"_blank")]/text()')
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值