【问题标题】:BeautifulSoup validate "title" td to extract values over multiple tablesBeautifulSoup 验证“标题”td 以提取多个表中的值
【发布时间】:2017-12-16 05:55:21
【问题描述】:

我正在尝试爬取一个旧网站,该网站没有标准化输出,也没有任何表格行上的样式/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>

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

我使用 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() 吗?

【问题讨论】:

标签: python html beautifulsoup web-crawler


【解决方案1】:

您可以创建标题列表并使用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''}

【讨论】:

    猜你喜欢
    • 2020-07-16
    • 1970-01-01
    • 2016-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-12
    • 2020-01-07
    • 1970-01-01
    相关资源
    最近更新 更多