正则表达式或其他返回这些值的方法(来自BeautifulSoup)

时间:2012-11-19 11:41:09

标签: python regex beautifulsoup

在stackoverflow社区的大量帮助下,我学到了很多关于python的知识,特别是使用BeautifulSoup进行抓取。我再次提到我用来学习相同的示例页面。

我有以下代码:

from bs4 import BeautifulSoup
import re

f = open('webpage.txt', 'r')
g = f.read()
soup = BeautifulSoup(g)

for heading in soup.find_all("td", class_="paraheading"):
    key = " ".join(heading.text.split()).rstrip(":")
    if key in columns:
        print key
        next_td = heading.find_next_sibling("td", class_="bodytext")
        value = " ".join(next_td.text.split())
        print value
    if key == "Industry Categories":
        print key
        ic_next_td = heading.find_next_sibling("td", class_="bodytext")
        print ic_next_td

来自此页面:

http://www.aidn.org.au/Industry-ViewCompany.asp?CID=3113

另存为webpage.txt会给我以下结果:

ACN
007 350 807
ABN
71 007 350 807
Annual Turnover
$5M - $10M
Number of Employees
6-10
QA
ISO9001-2008, AS9120B,
Export Percentage
5 %
Industry Categories
<td class="bodytext">Aerospace<br/>Land (Vehicles, etc)<br/>Logistics<br/>Marine<br/>Procurement<br/></td>
Company Email
lisa@aerospacematerials.com.au
Company Website
http://www.aerospacematerials.com.au
Office
2/6 Ovata Drive Tullamarine VIC 3043
Post
PO Box 188 TullamarineVIC 3043
Phone
+61.3. 9464 4455
Fax
+61.3. 9464 4422
到目前为止,这么好。会考虑将此写入CSV或其他内容,但是现在我想知道如何将<td class="bodytext">Aerospace<br/>Land (Vehicles, etc)<br/>Logistics<br/>Marine<br/>Procurement<br/></td>中包含的数据分开来分隔行?

像这样:

Industry Categories
Aerospace
Land (Vehicles, etc)
Logistics
Marine
Procurement

我尝试了一些正则表达式,例如:

if key == "Industry Categories":
        print key
        ic_next_td = heading.find_next_sibling("td", class_="bodytext")
        value = re.findall('\>(.*?)\<', ic_next_td)
        print value[0]

但我得到了eroor TypeError: expected string or buffer。我想我需要迭代findall或其他东西。

该方法需要足够通用,以处理相同格式的其他变体,例如“驴”和“驴”。或者&#39;船&#39;而不是&#39;航空航天&#39;或者&#39;后勤&#39; (在我想到的场景中,我不一定知道所有可能性。)

有没有办法使用br标签和美丽的汤或正则表达式来解决这个问题?

对不起,这有点长。一如既往,也非常高兴任何建议的代码优化,所以我可以继续学习正确构建Python脚本的最佳方法。

谢谢!

更新

此代码有效:

for heading in soup.find_all("td", class_="paraheading"):
    key = " ".join(heading.text.split()).rstrip(":")
    if key in columns:
        print key
        next_td = heading.find_next_sibling("td", class_="bodytext")
        value = " ".join(next_td.text.split())
        print value
    if key == "Industry Categories":
        print key
        ic_next_td = heading.find_next_sibling("td", class_="bodytext")
        for value in ic_next_td.strings:
                print value

并且此代码产生了缩进错误:

for heading in soup.find_all("td", class_="paraheading"):
    key = " ".join(heading.text.split()).rstrip(":")
    if key in columns:
        print key
        next_td = heading.find_next_sibling("td", class_="bodytext")
        value = " ".join(next_td.text.split())
        print value
    if key == "Industry Categories":
        print key
        ic_next_td = heading.find_next_sibling("td", class_="bodytext")
        for value in ic_next_td.strings:
            print value

注意工作代码中似乎是print value的双缩进。在我看来,下一级缩进将是for value in ic_next_td.strings:之后的单个缩进?

1 个答案:

答案 0 :(得分:3)

您必须进一步解析ic_next_td的内容。幸运的是,原始页面使用<br/>标记为您提供了分隔文本的位置。不要在这里使用正则表达式,BeautifulSoup有更好的工具:

for value in ic_next_td.strings:
    print value

会导致:

Aerospace
Land (Vehicles, etc)
Logistics
Marine
Procurement

您可以通过致电.strings iterator上的list()将所有这些内容存储在列表中:

values = list(ic_next_td.strings)