2025年2月14日 星期五 甲辰(龙)年 腊月十四 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > Python

python html 解析与正则表达式

时间:04-01来源:作者:点击数:57

#正则表达式

1.正则表达式的特殊字符

^/$开始/结束 \w/\W匹配字母,数字,下划线/相反

\s/\S匹配空白字符/相反 \d/D匹配数字/相反

\b/\B匹配单词开始和结束的位置/相反 .匹配任意字符

[m]匹配单个字符串 [m1m2...n]匹配多个字符串

[m-n]匹配m-n区间的数字,字母 [^m]匹配除m以外的字符串

()对正则表达式进行分组

2.正则表达式中的常用限定符

*匹配0次或多次 +匹配一次或多次 ?匹配一次或零次

{m}重复m次 {m,n}重复m到n次,省略n则为m到任意次

3.限定符与?的组合

*?匹配零次或多次,且最短匹配 +?匹配一次或多次,且最短匹配

??匹配一次或零次,且最短匹配 {m,n}?重复m-m次,且最短匹配

(?#...)正则表达式的注释 (?P<name>...)给分组命名,name为名称

(?P=name)使用名为name的分组 (注:此后面两种为python中的写法)

4.re模块的常用函数

findall(pattern,string,flags=0)#根据pattern在string中匹配字符串,若匹配成功返回结果列表,否则返回空列表,flags表示规则选项(可选).

sub(pattern,repl,string,count=0)#根据指定的正则表达式,替换源字符串中的子串,repl是用于替换的字符串,string是源字符串.

match(pattern,string,flags=0)#从头部开始匹配字符串,只返回1次匹配成功的对象,否则返回None.

compile(patter,flags=0)#编译正则表达式,返回1个pattern对象

split(pattern,string,maxsplit=0)#根据pattern分隔string,maxsplit表示最大的分隔数.

escape(pattern) #匹配字符串中的特殊字符,如*,+,?等.

5.re模块的规则选项

I忽略大小写 L字符集本地化,用以多语言环境

M多行匹配 S使用'.'匹配包括\n在内的所有字符

X忽略正则表达式的空白,换行 U\w\W\b\B\d\D\s\S都将使用Unicode

6.常用正则表达式:

E-mail地址:^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$

URL:^[a-zA-Z]+://(\w+(-\w+)*)(\.(\w+(-\w+)*))*(\?\s*)?$

或:^http:\/\/[A-Za-z0-9]+\.[A-Za-z0-9]+[\/=\?%\-&_~`@[\]\':+!]*([^<>\"\"])*$

邮政编码:^[1-9]\d{5}$

中文:^[\u0391-\uFFE5]+$

电话号码:^((\(\d{2,3}\))|(\d{3}\-))?(\(0\d{2,3}\)|0\d{2,3}-)?[1-9]\d{6,7}(\-\d{1,4})?$

手机号码:^((\(\d{2,3}\))|(\d{3}\-))?13\d{9}$

匹配空行:\n[\s| ]*\r

提取信息中的网络链接:(h|H)(r|R)(e|E)(f|F) *= *('|")?(\w|\\|\/|\.)+('|"| *|>)?

提取信息中的邮件地址:\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*

提取信息中的图片链接:(s|S)(r|R)(c|C) *= *('|")?(\w|\\|\/|\.)+('|"| *|>)?

提取信息中的IP地址:(\d+)\.(\d+)\.(\d+)\.(\d+)

IP: re.search(r'^(([01]?\d?\d?|2[0-4]?\d?|25[0-5]?)\.){3}([01]?\d?\d?|2[0-4]?\d?|25[0-5]?)$','1.14.183.1')

提取信息中的中国手机号码:(86)*0*13\d{9}

提取信息中的中国固定电话号码:(\(\d{3,4}\)|\d{3,4}-|\s)?\d{8}

提取信息中的中国电话号码(包括移动和固定电话):(\(\d{3,4}\)|\d{3,4}-|\s)?\d{7,14}

中文、英文、数字及下划线:^[\u4e00-\u9fa5_a-zA-Z0-9]+$

匹配中文字符的正则表达式: [\u4e00-\u9fa5]

匹配双字节字符(包括汉字在内):[^\x00-\xff]

代码示例:

  • import re
  • # 将正则表达式编译成pattern对象
  • pattern = re.compile(r'\d+')
  • # 一,match
  • # 使用 re.match 匹配文本,获得匹配结果
  • result = re.match(pattern,'123adb234')
  • print(result.group()) if result else print(result)
  • result2 = re.match(pattern,'adb234')
  • print(result2.group()) if result2 else print(result2)
  • # 执行结果:
  • '123'
  • None
  • # 二,search
  • result = re.search(pattern, 'abc123def')
  • print(result.group()) if result else print(result)
  • # 执行结果:
  • '123'
  • # 三,split
  • p = re.compile(r'[,|.|;|?]')
  • result = re.split(p, 'a.b?c,d.e.f;g')
  • print(result)
  • # 执行结果:
  • ['a', 'b', 'c', 'd', 'e', 'f', 'g']
  • # 四,findall
  • result = re.findall(pattern, 'a2b4sc1dd6')
  • print(result)
  • # 执行结果:
  • ['2', '4', '1', '6']
  • # 五,finditer
  • result = re.finditer(pattern, 'a4Bd2lh2fh23j')
  • print([match.group() for match in result])
  • # 执行结果:
  • ['4', '2', '2', '23']
  • # 六, sub
  • result = re.sub('[.|;|,|?]','','jdh.dh;e,jh?s')
  • print(result)
  • # 执行结果:
  • 'jdhdhejhs'
  • # 七, subn
  • s = 'i love world, hello world!'
  • p = re.compile(r'(\w+) (\w+)')
  • print(p.subn(r'\2 \1',s))
  • # 执行结果:
  • ('love i world, world hello!', 2)

bs4

1、基本操作

  • from bs4 import BeautifulSoup
  • html = """
  • <!DOCTYPE html>
  • <html>
  • <head>
  • <title>黄帝内经</title>
  • </head>
  • <body>
  • <p class="title"><b>素问·四气调神大论</b></p>
  • <p class="body">昔在黄帝,生而神灵,弱而能言,幼而徇齐,长而敦敏,成而登天。</p>
  • <p class="body">乃问于天师曰:余闻上古之人,春秋皆度百岁,而动作不衰;今时之人,年半百而动作皆衰者,时世异耶,人将失之耶。</p>
  • <a href="https://so.gushiwen.org/guwen/bookv_964.aspx" class="link" id="a1">上一篇</a>
  • <a href="https://so.gushiwen.org/guwen/bookv_966.aspx" class="link" id="a2">下一篇</a>
  • </body>
  • </html>
  • """
  • # 创建 BeautifulSoup 对象,两种方式
  • soup = BeautifulSoup(html,'lxml',from_encoding='utf-8') # 第一种
  • # soup = BeautifulSoup(open('test.html')) # 第二种
  • # 一、对象种类
  • print(soup.name)
  • # [document]
  • print(soup.title)
  • # <title>黄帝内经</title>
  • print(soup.title.name)
  • # title
  • soup.title.name = 'mytitle'
  • print(soup.title)
  • # None
  • print(soup.mytitle)
  • # <mytitle>黄帝内经</mytitle>
  • print(soup.p)
  • # <p class="title"><b>素问四气调神大论</b></p>
  • print(soup.p['class'])
  • # ['title']
  • soup.p['class'] = 'myclass'
  • print(soup.p)
  • # <p class="myclass"><b>素问四气调神大论</b></p>
  • print(soup.a.string)
  • # 上一篇
  • print(soup.find_all('p',limit=2))
  • # [<p class="myclass"><b>素问四气调神大论</b></p>, <p class="body">昔在黄帝,生而神灵,弱而能言,幼而徇齐,长而敦敏,成而 登天。</p>]

2、css 选择器

  • # 二、CSS选择器
  • print(soup.select('title'))
  • # [<title>黄帝内经</title>]
  • print(soup.select('.link'))
  • # [<a class="link" href="https://so.gushiwen.org/guwen/bookv_964.aspx">上一篇</a>, <a class="link" href="https://so.gushiwen.org/guwen/bookv_966.aspx">下一篇</a>]
  • print(soup.select('.link')[0].text)
  • print(soup.select('.link')[0].string)
  • # 上一篇
  • # 上一篇
  • # 逐层查找title标记
  • print(soup.select('html head title')) # [<title>黄帝内经</title>]
  • # 直接查找子节点
  • print(soup.select('head > title')) # [<title>黄帝内经</title>]
  • # 查找 body 下的 id='a2' 的标记
  • print(soup.select('body > #a2')) # [<a class="link" href="https://so.gushiwen.org/guwen/bookv_966.aspx" id="a2">下一篇</a>]
  • # 查找 a 标签 id 为 a2 的
  • print(soup.select('a#a2')) # [<a class="link" href="https://so.gushiwen.org/guwen/bookv_966.aspx" id="a2">下一篇</a>]

lxml

  • from lxml import etree
  • html_str = """
  • <html>
  • <head>
  • <link class='link' rel="dns-prefetch" href="//s1.bdstatic.com"/>
  • <link class='link' rel="dns-prefetch" href="//t1.baidu.com"/>
  • <link class='link' rel="dns-prefetch" href="//t2.baidu.com"/>
  • <link class='link' rel="dns-prefetch" href="//t3.baidu.com"/>
  • <link class='link' rel="dns-prefetch" href="//t10.baidu.com"/>
  • <link rel="dns-prefetch" href="//t11.baidu.com"/>
  • <link rel="dns-prefetch" href="//t12.baidu.com"/>
  • <link rel="dns-prefetch" href="//b1.bdstatic.com"/>
  • <title>百度一下,你就知道</title>
  • </head>
  • <body link="#0000cc">
  • <div id="wrapper" style="display:none;">
  • """
  • html = etree.HTML(html_str)
  • result = etree.tostring(html)
  • print(result)
  • # 输出:
  • """
  • <html>
  • <head>
  • <link class="link" rel="dns-prefetch" href="//s1.bdstatic.com"/>
  • <link class="link" rel="dns-prefetch" href="//t1.baidu.com"/>
  • <link class="link" rel="dns-prefetch" href="//t2.baidu.com"/>
  • <link class="link" rel="dns-prefetch" href="//t3.baidu.com"/>
  • <link class="link" rel="dns-prefetch" href="//t10.baidu.com"/>
  • <link rel="dns-prefetch" href="//t11.baidu.com"/>
  • <link rel="dns-prefetch" href="//t12.baidu.com"/>
  • <link rel="dns-prefetch" href="//b1.bdstatic.com"/>
  • <title>&#176;&#217;&#182;&#200;&#210;&#187;&#207;&#194;&#163;&#172;&#196;&#227;&#190;&#205;&#214;&#170;&#181;&#192;</title>
  • </head>
  • <body link="#0000cc">
  • <div id="wrapper" style="display:none;">
  • </div></body></html>
  • """
  • # 可以发现,lxml帮我们修正了html代码
  • # XPath
  • """
  • XPath 语法
  • 表达式 描述
  • nodename 选取此节点的所有子节点
  • / 从根节点选取
  • // 选取任意位置的某个节点
  • . 选取当前节点
  • .. 选取当前节点的父节点
  • @ 选取属性
  • """
  • from lxml import etree
  • html = etree.parse('index.html')
  • result = etree.tostring(html, pretty_print=True)
  • print(result)
  • urls = html.xpath(".//*[@class='link']/@href")
  • print(urls)
  • # 输出:
  • # ['//s1.bdstatic.com', '//t1.baidu.com', '//t2.baidu.com', '//t3.baidu.com', '//t10.baidu.com']
方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门