【问题标题】:Parsing Help in PythonPython 中的解析帮助
【发布时间】:2015-12-07 23:33:08
【问题描述】:

有人可以帮我解析一下吗?我有很多麻烦。我正在解析来自这个site 的信息。

下面是几行代码,它们从具有 2 个标题和 4 个值的表中提取数据:

for x in soup.findAll(attrs={'valign':'top'}):
                print(x.contents)
                make_list = x.contents
                print(make_list[1]) #trying to select one of the values on the list. 

当我尝试使用make_list[1] 行打印它时,会出现错误。但是,如果我拉出最后 2 行,我会得到我想要的列表格式的 html,但我似乎无法分离单个的或过滤它们(取出 html 标签)。有人可以帮忙吗?

这是一个输出示例,我想在此处具体说明。我不确定正确的正则表达式:

 ['\n', <td align="left">Western Mutual/Residence <a href="http://interactive.web.insurance.ca.gov/companyprofile/companyprofile?event=companyProfile&amp;doFunction=getCompanyProfile&amp;eid=3303"><small>(Info)</small></a></td>, '\n', <td align="left"><div align="right">           355</div></td>, '\n', <td align="left"><div align="right">250</div></td>, '\n', <td align="left"> </td>, '\n', <td align="left">Western Mutual/Residence <a href="http://interactive.web.insurance.ca.gov/companyprofile/companyprofile?event=companyProfile&amp;doFunction=getCompanyProfile&amp;eid=3303"><small>(Info)</small></a></td>, '\n', <td align="left"><div align="right">           320</div></td>, '\n', <td align="left"><div align="right">500</div></td>, '\n']

【问题讨论】:

  • 预期输出是什么
  • “出现错误”。什么错误?
  • @Kevin IndexError: 列表索引超出范围
  • @VigneshKalai 表 1 - 公司名称:Western Mutual/Residence Premium:355 自付额:250 Sheet 2 - 公司名称:Western Mutual/Residence Premium:320 自付额:500 类似
  • “IndexError”是您得到的唯一输出吗?或者它在崩溃之前是否成功打印了一些内容?您认为此错误是在循环的第一次迭代中发生还是在以后发生?

标签: python html regex parsing beautifulsoup


【解决方案1】:

如果您尝试解析来自该网站的结果,以下应该可以工作:

from bs4 import BeautifulSoup

html_doc = ....add your html....
soup = BeautifulSoup(html_doc, 'html.parser')
rows = []
tables = soup.find_all('table')
t2 = None

# Find the second from last table
for t3 in tables:
    t1, t2 = t2, t3

for row in t1.find_all('tr'):
    cols = row.find_all(['td', 'th'])
    cols = [col.text.strip() for col in cols]
    rows.append(cols)

# Collate the two columns
data = [cols[0:3] for cols in rows]
data.extend([cols[4:7] for cols in rows[1:]])

for row in data:
    print "{:40}  {:15} {}".format(row[0], row[1], row[2])

这让我的输出看起来像:

Company Name                              Annual Premium  Deductible
AAA (Interinsurance Exchange) (Info)      N/A             250
Allstate (Info)                           315             250
American Modern (Info)                    N/A             250
Amica Mutual (Info)                       259             250
Bankers Standard (Info)                   N/A             250
California Capital  (Info)                160             250
Century National (Info)                   N/A             250
.....

它是如何工作的?

由于网页主要是显示一个表格,这是我们需要找到的,所以第一步是获取表格列表。

该网站在多个部分中使用了表格。页面结构有可能至少在请求之间保持不变。

我们需要的表格几乎是页面上的最后一个(但不是最后一个),所以我决定遍历可用的表格并选择倒数第二个。 t1 t2 t3 只是在迭代时保留最后一个值的一种解决方法。

从这里开始,HTML 表格通常具有相当标准的结构,TRTD。这个也使用TH 作为标题行。然后使用这个table BeautifulSoup 允许我们枚举所有行。

然后我们可以找到每一行的所有列。如果您打印返回的内容,您将看到每一行的所有条目,然后您可以看到需要哪些索引来对其进行切片。

他们在两个列组中显示了输出,中间有一个空白列。我构建了两个列表,提取两组列,然后将第二组附加到第一组的底部以进行显示。

【讨论】:

  • 天哪,谢谢,我会试试看...这与我的想法完全不同...但我不明白您如何在网页中找到 t1、t2、t3 ?你是如何找到这些以便我知道未来的桌子的?谢谢你,我会试试这个,让你知道它是如何工作的:)
  • 你怎么知道要专门寻找'td'和'th'?我一直在做的是右键单击并检查元素并尝试查看并理解该代码哈哈。
  • 你是怎么得到数字 0,3,4,7,40,15 的?大声笑很抱歉打扰你问......但也谢谢你!
  • 我已经添加了关于用于解决问题的方法的解释。希望你觉得这很有用。为了解决这类问题,您确实需要掌握 HTML。
  • 感谢您的帮助!通过检查 elemtn 我可以看到它们似乎包含 标记内的所有内容。 TH 是标题,你是对的.... 但是 TR 和 TD 有什么区别?似乎 TD 仅用于数字,而 TR 用于整行。我是否以错误的方式看待事物,或者这是解释表格源代码的正确方式?新手见谅,我还在学习中。再次感谢您对我的帮助,我会牢记这一课。稍后会告诉你它的样子!
猜你喜欢
  • 2011-08-15
  • 1970-01-01
  • 2023-03-26
  • 1970-01-01
  • 1970-01-01
  • 2017-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多