使用 BeautifulSoup 像 Javascript 一样解析 DOM



我在变量html_doc中有一个示例HTML,如下所示:

html_doc =  """<table class="sample">
<tbody>
<tr class="title"><td colspan="2">Info</td></tr>
<tr>
<td class="light">Time</td>
<td>01/01/1970, 00:00:00</td>
</tr>
<td class="highlight">URL</td>
<td>https://test.com</td>
</tr>
</tbody>
</table>"""

如果我想解析 DOM,使用 Javascript 非常简单。但是,如果我只想从上面的<td>标签中获取 URL(https://test.com)Time (01/01/1970, 00:00:00)2 个不同的变量,如果没有与之关联的类名,我该怎么办。

我的test.py文件

from bs4 import BeautifulSoup
soup = BeautifulSoup(html_doc,'html.parser')
test = soup.find_all("td")
print(test)

你已经得到了所有td元素。您可以遍历所有这些:

for td in soup.find_all('td'):
if td.text.startswith('http'):
print(td, td.text)
# <td>https://test.com</td> https://test.com

如果需要,您可以通过搜索带有"highlight"类的td元素并找到下一个同级元素来不那么明确,但是如果DOM会更改,这更容易出错:

for td in soup.find_all('td', {'class': 'highlight'}):
print(td.find_next_sibling())
# <td>https://test.com</td>

您可以尝试使用正则表达式来获取网址

from bs4 import BeautifulSoup
import re
soup = BeautifulSoup(html_doc,'html.parser')
test = soup.find_all("td")
for tag in test:
urls = re.match('https?://(?:[-w.]|(?:%[da-fA-F]{2}))+', tag.text)
time = re.match('[0-9/:, ]+',tag.text)
if urls!= None:
print(urls.group(0))
if time!= None:
print(time.group(0))

输出

1970/01/01, 00:00:00
https://test.com

这是一个非常具体的解决方案。如果你需要一个通用的方法,Hari Krishnan的解决方案可能更合适,有一些调整。

from bs4 import BeautifulSoup
soup = BeautifulSoup(html_doc,'html.parser')
tds = []
for td in soup.find_all('td', {'class': ['highlight', 'light']}):
tds.append(td.find_next_sibling().string)
time, link = tds

参考@DeepSpace

import bs4, re
from bs4 import BeautifulSoup
html_doc =  """<table class="sample">
<tbody>
<tr class="title"><td colspan="2">Info</td></tr>
<tr>
<td class="light">Time</td>
<td>01/01/1970, 00:00:00</td>
</tr>
<td class="highlight">URL</td>
<td>https://test.com</td>
</tr>
</tbody>
</table>"""
datepattern = re.compile("d{2}/d{2}/d{4}, d{2}:d{2}:d{2}")
soup = BeautifulSoup(html_doc,'html.parser')
for td in soup.find_all('td'):
if td.text.startswith('http'):
link = td.text
elif datepattern.search(td.text):
time = td.text
print(link, time)

相关内容

最新更新