3

我正在尝试学习网络抓取和 python(以及相关的编程),并找到了 BeautifulSoup 库,它似乎提供了很多可能性。

我正在尝试找出如何最好地从此页面中提取相关信息:

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

我可以对此进行更详细的介绍,但基本上是公司名称、关于它的描述、联系方式、各种公司详细信息/统计数据等

在这个阶段,研究如何干净地隔离这些数据并刮掉它,以期将它们全部放在 CSV 或其他东西中。

我很困惑如何使用 BS 来获取不同的表数据。有很多 tr 和 td 标签,不知道如何锚定任何独特的东西。

我想出的最好的方法是以下代码作为开始:

from bs4 import BeautifulSoup
import urllib2

html = urllib2.urlopen("http://www.aidn.org.au/Industry-ViewCompany.asp?CID=3113")
soup = BeautifulSoup(html)
soupie = soup.prettify()
print soupie

然后从那里使用正则表达式等从清理的文本中提取数据。

但是必须有更好的方法来使用 BS 树来做到这一点?或者这个网站的格式是 BS 不会提供更多帮助的吗?

不寻找完整的解决方案,因为这是一个很大的问题,我想学习,但是任何让我上路的代码片段都将不胜感激。

更新

感谢下面的@ZeroPiraeus,我开始了解如何解析表格。这是他的代码的输出:

=== Personnel ===
bodytext    Ms Gail Morgan CEO
bodytext    Phone: +61.3. 9464 4455 Fax: +61.3. 9464 4422
bodytext    Lisa Mayoh Sales Manager
bodytext    Phone: +61.3. 9464 4455 Fax: +61.3. 9464 4422 Email: bob@aerospacematerials.com.au

=== Company Details ===
bodytext    ACN: 007 350 807 ABN: 71 007 350 807 Australian Owned Annual Turnover: $5M - $10M Number of Employees: 6-10 QA: ISO9001-2008, AS9120B, Export Percentage: 5 % Industry Categories: AerospaceLand (Vehicles, etc)LogisticsMarineProcurement 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
paraheading ACN:
bodytext    007 350 807
paraheading ABN:
bodytext    71 007 350 807
paraheading 
bodytext    Australian Owned
paraheading Annual Turnover:
bodytext    $5M - $10M
paraheading Number of Employees:
bodytext    6-10
paraheading QA:
bodytext    ISO9001-2008, AS9120B,
paraheading Export Percentage:
bodytext    5 %
paraheading Industry Categories:
bodytext    AerospaceLand (Vehicles, etc)LogisticsMarineProcurement
paraheading Company Email:
bodytext    lisa@aerospacematerials.com.au
paraheading Company Website:
bodytext    http://www.aerospacematerials.com.au
paraheading Office:
bodytext    2/6 Ovata Drive Tullamarine VIC 3043
paraheading Post:
bodytext    PO Box 188 TullamarineVIC 3043
paraheading Phone:
bodytext    +61.3. 9464 4455
paraheading Fax:
bodytext    +61.3. 9464 4422

我的下一个问题是,将这些数据放入适合导入电子表格的 CSV 的最佳方法是什么?例如,将“ABN”“ACN”“公司网站”等内容作为列标题,然后将相应的数据作为行信息。

谢谢你的帮助。

4

2 回答 2

3

您的代码将完全取决于您想要什么以及您希望如何存储它,但是这个片段应该让您了解如何从页面中获取相关信息:

import requests

from bs4 import BeautifulSoup

url = "http://www.aidn.org.au/Industry-ViewCompany.asp?CID=3113"
html = requests.get(url).text
soup = BeautifulSoup(html)

for feature_heading in soup.find_all("td", {"class": "Feature-Heading"}):
    print "\n=== %s ===" % feature_heading.text
    details = feature_heading.find_next_sibling("td")
    for item in details.find_all("td", {"class": ["bodytext", "paraheading"]}):
        print("\t".join([item["class"][0], " ".join(item.text.split())]))

我找到requests了一个比 更愉快的图书馆urllib2,但这当然取决于你。

编辑:

为了回答您的后续问题,您可以使用以下内容从抓取的数据中写入 CSV 文件:

import csv
import requests

from bs4 import BeautifulSoup

columns = ["ACN", "ABN", "Annual Turnover", "QA"]
urls = ["http://www.aidn.org.au/Industry-ViewCompany.asp?CID=3113", ] # ... etc.

with open("data.csv", "w") as csv_file:
    writer = csv.DictWriter(csv_file, columns)
    writer.writeheader()
    for url in urls:
        soup = BeautifulSoup(requests.get(url).text)
        row = {}
        for heading in soup.find_all("td", {"class": "paraheading"}):
            key = " ".join(heading.text.split()).rstrip(":")
            if key in columns:
                next_td = heading.find_next_sibling("td", {"class": "bodytext"})
                value = " ".join(next_td.text.split())
                row[key] = value
        writer.writerow(row)
于 2012-11-12T19:32:31.953 回答
0

我曾经在这条路上走过。我使用的 html 页面的格式始终与表格相同,并且是公司内部的。我们确保客户知道,如果他们更改页面,很可能会破坏编程。通过该规定,能够通过 tr 和 td 列表中的索引值确定所有内容的位置。这远非拥有他们无法或不愿提供的 XML 数据的理想情况,但已经完美运行了将近一年。如果有人知道更好的答案,我也想知道。那是我第一次也是唯一一次使用 Beautiful Soup,从那以后就再也不需要它了,但效果很好。

于 2012-11-12T17:56:59.660 回答