BeautifulSoup验证“title”td以提取多个表的值

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BeautifulSoup验证“title”td以提取多个表的值相关的知识,希望对你有一定的参考价值。

我正在尝试抓取一个没有标准化输出且没有任何样式表行的样式/ id标记的旧网站,它们只是显示如下:

<table BORDER="0" VALIGN="top" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
	<tr>
		<td ALIGN="left" VALIGN="top" WIDTH="175">
			<strong>Surname</strong>
		</td>
		<td valign="top">
Bloggs
		</td>
	</tr>
	<tr>
		<td ALIGN="left" VALIGN="top" WIDTH="175">
			<strong>Forename(s)</strong>
		</td>
		<td valign="top">
Joe
		</td>
	</tr>
	<tr>
		<td ALIGN="left" VALIGN="top" WIDTH="175">
			<strong>Title</strong>
		</td>
		<td valign="top">
Mr
		</td>
	</tr>
	<tr>
	    <td ALIGN="left" VALIGN="top" WIDTH="175">
			<strong>Gender</strong>
		</td>
		<td valign="top">
Male
		</td>
	</tr>
	<tr>
		<td ALIGN="left" VALIGN="top" WIDTH="175">
			<strong>Occupation</strong>
		</td>
		<td valign="top">

		</td>
	</tr>
	<tr>
		<td ALIGN="left" VALIGN="top" WIDTH="175">
			<strong>Date of Birth</strong>
		</td>
		<td valign="top">
13/05/12
		</td>
	</tr>
</table>

问题是,如果db中不存在某个字段,它甚至不会显示空行,则会在两个核心数据表之间添加一些额外的数据作为额外的表,并且在发生这种情况时没有指示。

我使用Python的方法有点长,但想法是将左侧TD作为标题进行验证并抓住正确的TD,这是相关数据,如下所示:

title, forename, surname, gender, occupation, dob = '', '', '', '', '', ''

tbl1 = soup.findAll('table')[1]

for tr in tbl1.findAll('tr'):
    content = tr.findAll('td')
    if content[0].text.strip() == 'Title':
        title = content[1].text.strip()
    if content[0].text.strip() == 'Forename(s)':
        forename = content[1].text.strip()
    if content[0].text.strip() == 'Surname':
        surname = content[1].text.strip()
    if content[0].text.strip() == 'Gender':
        gender = content[1].text.strip()
    if content[0].text.strip() == 'Occupation':
        occupation = content[1].text.strip()
    if content[0].text.strip() == 'Date of Birth':
        dob = content[1].text.strip()

print('"' + title + '","' + forename + '","' + surname + '","' + gender + '","' + occupation + '","' + dob + '"')

每当我尝试迭代所有表时,我得到:AttributeError:ResultSet对象没有属性'findAll'。您可能正在处理像单个项目的项目列表。当你打算调用find()时,你调用了find_all()吗?

答案

您可以创建标题列表并使用itertools.izip_longest

import itertools
import re
headers = ['title', 'forename', 'surname', 'gender', 'occupation', 'dob']
from bs4 import BeautifulSoup as soup 
s = soup(web_data, 'lxml')
new_s = [re.sub('\n+|\t+', '', i.text) for i in s.findAll('td')]
final_data = {a:b for a, b in itertools.izip_longest(headers, [c for i, c in enumerate(new_s) if i%2 != 0])}

输出:

{'surname': u'Mr', 'title': u'Bloggs', 'dob': u'13/05/12', 'gender': u'Male', 'forename': u'Joe', 'occupation': u''}

以上是关于BeautifulSoup验证“title”td以提取多个表的值的主要内容,如果未能解决你的问题,请参考以下文章

Python beautifulsoup 获取标签中的值 怎么获取?

在 BeautifulSoup 中选择标签的问题

BeautifulSoup 4、findNext()函数

BeautifulSoup标签定位方法总结

Beautifulsoup - nextSibling

如何将 BeautifulSoup HREF 搜索从 <a> 扩展到 <td>