使用BeautifulSoup像Javascript一样解析DOM

时间:2018-09-12 11:57:44

标签: python beautifulsoup

我在这样的变量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非常简单。但是,如果我只想从上面的(https://test.com)标签中截取两个不同的变量中的URL Time (01/01/1970, 00:00:00)<td>,如果没有与之关联的类名,该怎么办? / p>

我的test.py文件

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

4 个答案:

答案 0 :(得分:2)

您已经拥有所有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>

答案 1 :(得分:0)

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

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年1月1日,00:00:00
  https://test.com

答案 2 :(得分:0)

这是一个非常具体的解决方案。如果您需要通用方法,则可以通过一些调整对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

答案 3 :(得分:0)

参考@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)