【问题标题】:Python BeautifulSoup Automatically tracking content table rows andcolumnsPython BeautifulSoup 自动跟踪内容表的行和列
【发布时间】:2011-07-30 04:27:13
【问题描述】:

首先让我说我是 Stack 和 Python 的新手。我上周才开始使用它。然而,我是一个经验丰富的 PHP/C++/Pascal/ADA/B/Forth(显示我的年龄)程序员。

我编写了一个脚本,它从网站中提取产品页面并将它们存储在我的本地 MySQL 数据库中。我这样做是为了在深夜负载较轻的时候抓取该站点。我现在需要对每个页面的 html 进行排序并获取产品描述。这些被放置在表格中。但是,每个页面可能在不同的行/列中有所需的值。

我可以确定的是:

  • 每个表格都有一个标题,用于定义其下方行/列中的数据。
  • 每个值的标题文本是一致的,即“零件”始终描述零件类型和“零件编号”总是描述一个部件号。
  • 并非所有页面都包含所需的所有数据。因此,如果未找到,则必须保存找到的内容。

在下面的部分中,它是第二部分,获取我遇到问题的数据值。如何从一行中选择第 n 列?

我目前的做法是:

获取所需的列

  • 从 db 获取 html 文档
  • 抓取表格(我的表格始终包含在页面上唯一的 div 中。
  • 抓取所有行(真的只需要对第一行执行此操作)
  • 当我找到所需的字段名称时,为每一行获取行和列索引。

获取数据值

  • 对于每一行:
  • 如果是标题则跳过该行(保存带有标题字段的行数)
  • 为每一列获取文本值。
  • 将值保存到数据库

我的页面的重要部分如下所示:

<div>
   ... 
   <table>
      <tr><td>&nbsp;</td><td><b>Item</b></td><td>&nbsp;</td><td><b>Description</b></td><td>&nbsp;</td><td><b>Part No.</b></td><td>&nbsp;</td><td><b>Color</b></td><td>&nbsp;</td></tr>
      <tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td></tr>
      <tr><td>&nbsp;</td><td>Toaster</td><td>&nbsp;</td><td>2-Slice</td><td>&nbsp;</td><td>#25713</td><td>&nbsp;</td><td>Chorme</td><td>&nbsp;</td></tr>
   </table>
   ...
</div>

非常感谢任何回复的人。

【问题讨论】:

  • BeautifulSoup 的特殊问题是什么?究竟是什么不工作或没有记录?到目前为止你写的代码在哪里?看起来像家庭作业...

标签: python html-parsing beautifulsoup web-crawler


【解决方案1】:

以下是使用 HTQL 的方法:

import htql;
doc = '''<div>     <table>
    <tr><td>&nbsp;</td><td><b>Item</b></td><td>&nbsp;</td><td><b>Description</b></td><td>&nbsp;        </td><td><b>Part No.</b></td><td>&nbsp;</td><td><b>Color</b></td><td>&nbsp;</td></tr>
    <tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td></tr>
    <tr><td>&nbsp;</td><td>Toaster</td><td>&nbsp;</td><td>2-Slice</td><td>&nbsp;</td><td>#25713</td><td>&nbsp;</td><td>Chorme</td><td>&nbsp;</td></tr>
  </table>  </div>''';

query = "<div>.<table>.<tr>{item=<td (th='Item')>&tx; desc=<td (th='Description')>&tx | item<>'Item'}";

for item, desc in htql.HTQL(doc, query): 
    print(item, desc); 

【讨论】:

  • 分号是字段分隔符。
  • 我指的是行尾的那些。 Python 对它们没有用处。
【解决方案2】:

我会这样处理它:

from BeautifulSoup import BeautifulSoup

doc = '''<div>
   <table>
      <tr><td>&nbsp;</td><td><b>Item</b></td><td>&nbsp;</td><td><b>Description</b></td><td>&nbsp;</td><td><b>Part No.</b></td><td>&nbsp;</td><td><b>Color</b></td><td>&nbsp;</td></tr>
      <tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td></tr>
      <tr><td>&nbsp;</td><td>Toaster</td><td>&nbsp;</td><td>2-Slice</td><td>&nbsp;</td><td>#25713</td><td>&nbsp;</td><td>Chorme</td><td>&nbsp;</td></tr>
   </table>
</div>'''

soup = BeautifulSoup(doc)
# find the table element in the HTML document
table = soup.find("table")
# grabs the top row
firstRow = table.contents[0]
# find how many columns there are
numberOfColumns = len(firstRow.contents)
restOfRows = table.contents[1:]
for row in restOfRows:
  for x in range(0,numberOfColumns):
    print "column data: %s" % row.contents[x].string

这将从任何文档中提取表格元素。然后根据第一行查找列数。最后,它将遍历其余行,打印出该行中的数据。

BS 文档的有用链接:http://www.crummy.com/software/BeautifulSoup/documentation.html

【讨论】:

  • 当我运行这段代码时,我得到了同样的错误,我不断地得到我自己的代码。属性错误:NavigableString 在行上没有属性“内容”:numberOfColumns = len(firstRow.contents)。如果这很重要,我正在使用 Python 2.6.6。
  • 该错误表明“firstRow”变量只是一个TextNode。打印出“firstRow”,看看返回了什么。
猜你喜欢
  • 1970-01-01
  • 2011-05-08
  • 1970-01-01
  • 1970-01-01
  • 2020-10-21
  • 1970-01-01
  • 2017-11-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多