![](/img/trans.png)
[英]The pythonic way to parse a small html code with beautifulsoup?
[英]Please help parse this html table using BeautifulSoup and lxml the pythonic way
我搜索了很多有關BeautifulSoup的內容,並建議使用lxml作為BeautifulSoup的未來,盡管這很有意義,但我很難從網頁上的所有表列表中解析出下表。
我對三列感興趣,這三列具有不同的行數,具體取決於頁面和檢查時間。 一個BeautifulSoup和lxml解決方案受到高度贊賞。 這樣,我可以要求管理員在開發人員上安裝lxml。 機。
所需輸出:
Website Last Visited Last Loaded
http://google.com 01/14/2011
http://stackoverflow.com 01/10/2011
...... more if present
以下是凌亂網頁中的代碼示例:
<table border="2" width="100%">
<tbody><tr>
<td width="33%" class="BoldTD">Website</td>
<td width="33%" class="BoldTD">Last Visited</td>
<td width="34%" class="BoldTD">Last Loaded</td>
</tr>
<tr>
<td width="33%">
<a href="http://google.com"</a>
</td>
<td width="33%">01/14/2011
</td>
<td width="34%">
</td>
</tr>
<tr>
<td width="33%">
<a href="http://stackoverflow.com"</a>
</td>
<td width="33%">01/10/2011
</td>
<td width="34%">
</td>
</tr>
</tbody></table>
>>> from lxml import html
>>> table_html = """"
... <table border="2" width="100%">
... <tbody><tr>
... <td width="33%" class="BoldTD">Website</td>
... <td width="33%" class="BoldTD">Last Visited</td>
... <td width="34%" class="BoldTD">Last Loaded</td>
... </tr>
... <tr>
... <td width="33%">
... <a href="http://google.com"</a>
... </td>
... <td width="33%">01/14/2011
... </td>
... <td width="34%">
... </td>
... </tr>
... <tr>
... <td width="33%">
... <a href="http://stackoverflow.com"</a>
... </td>
... <td width="33%">01/10/2011
... </td>
... <td width="34%">
... </td>
... </tr>
... </tbody></table>"""
>>> table = html.fromstring(table_html)
>>> for row in table.xpath('//table[@border="2" and @width="100%"]/tbody/tr'):
... for column in row.xpath('./td[position()=1]/a/@href | ./td[position()>1]/text() | self::node()[position()=1]/td/text()'):
... print column.strip(),
... print
...
Website Last Visited Last Loaded
http://google.com 01/14/2011
http://stackoverflow.com 01/10/2011
>>>
瞧!)當然,您可以將值添加到嵌套列表或字典中,而不用打印;)
這是一個使用elementtree及其提供的有限XPath的版本:
from xml.etree.ElementTree import ElementTree
doc = ElementTree().parse('table.html')
for t in doc.findall('.//table'):
# there may be multiple tables, check we have the right one
if t.find('./tbody/tr/td').text == 'Website':
for tr in t.findall('./tbody/tr/')[1:]: # skip the header row
tds = tr.findall('./td')
print tds[0][0].attrib['href'], tds[1].text.strip(), tds[2].text.strip()
結果:
http://google.com 01/14/2011
http://stackoverflow.com 01/10/2011
這是使用HTMLParser的版本。 我嘗試了pastebin.com/tu7dfeRJ的內容。 它處理meta標簽和doctype聲明,兩者都挫敗了ElementTree版本。
from HTMLParser import HTMLParser
class MyParser(HTMLParser):
def __init__(self):
HTMLParser.__init__(self)
self.line = ""
self.in_tr = False
self.in_table = False
def handle_starttag(self, tag, attrs):
if self.in_table and tag == "tr":
self.line = ""
self.in_tr = True
if tag=='a':
for attr in attrs:
if attr[0] == 'href':
self.line += attr[1] + " "
def handle_endtag(self, tag):
if tag == 'tr':
self.in_tr = False
if len(self.line):
print self.line
elif tag == "table":
self.in_table = False
def handle_data(self, data):
if data == "Website":
self.in_table = 1
elif self.in_tr:
data = data.strip()
if data:
self.line += data.strip() + " "
if __name__ == '__main__':
myp = MyParser()
myp.feed(open('table.html').read())
希望這可以滿足您的所有需求,並且您可以接受此答案。 根據要求更新。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.