我需要通过匹配html中的字符串来提取html中的父标签。 (即) 我有很多原始的html源代码。每个来源都包含文字值“VIN: * ”**以及一些字符。此文本值(VIN: * )在每个来源中以各种格式放置,例如“< ul>” ,“< div>”等。
然后我需要提取所有值以及“VIN: * ”字符串。这意味着我需要获取其父标签。
例如,
<div class="class1">
Stock Number:
Z2079
<br>
**VIN:
2T2HK31UX9C110701**
<br>
Model Code:
9424
<img class="imgcert" src="/images/Lexus_cpo.jpg">
</div>
这里我有html源的“VIN”。类似于我对其他html源也有不同格式的VIN。
必须在Python中提取这些值。
有没有办法通过有效的方式匹配Python中的字符串来提取父标记?
答案 0 :(得分:2)
我强烈建议在BeautifulSoup上使用;它为解析HTML提供了一些非常方便的功能。例如,在这两种情况下,我将如何寻找包含“VIN”的每个文本节点:
soup = your_html_here
vins = soup.findAll(text = lambda(x): x.lower.index('vin') != -1)
从那里,您只需遍历该集合,抓住每个节点的父节点,抓住所述父节点的内容,并按您认为合适的方式解析它们:
for v in vins:
parent_html = v.parent.contents
# more code here
答案 1 :(得分:1)
对于一个如此简单的任务,它包含ANLYZING字符串,而不是PARSING它(解析=构建文本的树表示),你可以这样做:
文字
ss = '''
Humpty Dumpty sat on a wall
<div class="class1">
Stock Number:
Z2079
<br>
**VIN:
2T2HK31UX9C110701**
<br>
Model Code:
9424
<img class="imgcert" src="/images/Lexus_cpo.jpg">
</div>
Humpty Dumpty had a great fall
<ul cat="zoo">
Stock Number:
ARDEN3125
<br>
**VIN:
SHAKAMOSK-230478-UBUN**
</br>
Model Code:
101
<img class="imgcert" src="/images/Magana_cpo.jpg">
</ul>
All the king's horses and all the king's men
<artifice>
<baradino>
Stock Number:
DERT5178
<br>
**VIN:
Pandaia-67-Moro**
<br>
Model Code:
1234
<img class="imgcert" src="/images/Pertuis_cpo.jpg">
</baradino>
what what what who what
<somerset who="maugham">
Nothing to declare
</somerset>
</artifice>
Couldn't put Humpty Dumpty again
<ending rtf="simi">
Stock Number:
ZZZ789
<br>
**VIN:
0000012554-ENDENDEND**
<br>
Model Code:
QS78-9
<img class="imgcert" src="/images/Sunny_cpo.jpg">
</ending>
qsdjgqsjkdhfqjkdhgfjkqshgdfkjqsdjfkh'''
代码:
import re
regx = re.compile('<([^ >]+) ?([^>]*)>'
'(?!.+?<(?!br>)[^ >]+>.+?<br>.+?</\\1>)'
'.*?\*\*VIN:(.+?)\*\*.+?</\\1>',
re.DOTALL)
li = [ (mat.group(1),mat.group(2),mat.group(3).strip(' \n\r\t'))
for mat in regx.finditer(ss) ]
for el in li:
print '(%-15r, %-25r, %-25r)' % el
结果
('div' , 'class="class1"' , '2T2HK31UX9C110701' )
('ul' , 'cat="zoo"' , 'SHAKAMOSK-230478-UBUN' )
('baradino' , '' , 'Pandaia-67-Moro' )
('ending' , 'rtf="simi"' , '0000012554-ENDENDEND' )
re.DOTALL
必须为点符号提供匹配换行符的能力(默认情况下,正则表达式模式中的点匹配除换行符之外的每个字符)
\\1
是指定在被检查字符串中的这个位置,必须有第一组捕获的字符串的相同部分,即部分([^ >]+)
'(?!.+?<(?!br>)[^ >]+>.+?<br>.+?</\\1>)'
是指在开始标记与HTML元素的结束标记之间遇到第一个标记<br>
之前,禁止在<br>
之外找到标记的部分。
此部分对于在VIM分开<br>
之前捕获最接近的前一个标记是必要的
如果此部分不存在,则使用正则表达式
regx = re.compile('<([^ >]+) ?([^>]*)>'
'.*?\*\*VIN:(.+?)\*\*.+?</\\1>',
re.DOTALL)
获得以下结果:
('div' , 'class="class1"' , '2T2HK31UX9C110701' )
('ul' , 'cat="zoo"' , 'SHAKAMOSK-230478-UBUN' )
('artifice' , '' , 'Pandaia-67-Moro' )
('ending' , 'rtf="simi"' , '0000012554-ENDENDEND' )
区别在于'技巧'而不是'baradino'
答案 2 :(得分:0)
对于不使用任何xml / html-parser的纯字符串版本,您可以尝试正则表达式(重新):
import re
html_doc = """ <div ...VIN ... /div>"""
results = re.findall('<(.+>).*VIN.*+</\1', html_doc)