我想从html文件中收集数据,然后将一些数据放入变量或列表中。 但我不太了解美丽的汤。特别是如何浏览结构。
这里获取src url属性的最佳方法是什么? :
<div id="headshot">
<img title="Photo of someone" alt="Photo of somenone" src="url/file.jpg">
</div>
这里如何导航并将p类值放入列表中? :
<p class="bioheading">value</p>
<div class="biodata">value</div>
<p class="bioheading">value</p>
<p class="biodata">value</p>
<p class="bioheading">value</p>
<p class="biodata"><a href"http://url.com/month=01&year=2018&day=02">January 01, 1900</a> (117 years old)</p>
<p class="bioheading">value</p>
<p class="biodata">value</p>
<p class="bioheading">value</p>
<p class="biodata">value</p>
同样的:
<div id="vitalbox" class="tab-content">
<div role="tabpanel" class="tab-pane active" id="home">
<div class="row">
<div class="col-xs-12 col-sm-4">
<p class="bioheading">value</p>
<p class="biodata">value</p>
<p class="bioheading">value</p>
<p class="biodata">value</p>
<p class="bioheading">value</p>
<p class="biodata">value</p>
</div>
这里如何获得性别价值? :
<input name="Gender" value="m" type="hidden">
特别是这个HTML可能会出错。 对不起这个初学者的问题。
最好的问候。
编辑:
k=0
a_table=[]
bday1=''
for link in soup.findAll('a'):
a_table.append(str(link.get('href')))
#out.write(str(i)+'\t'+str(p.text)+'\n')
if re.match(regs4,str(link.get('href')),re.M) != None:
bday1 = re.search(regs1,str(link.get('href')),re.M)
else:
bday1 = 'http://url.com/calendar.asp?calmonth=01&calyear=2018&calday=01'
k=k+1
我试着收集一个href =并检查它是否需要url。与正则表达式 .find_All()将无法正常运行错误:
builtins.TypeError: 'NoneType' object is not callable
所以我正在使用.findAll()
这也不起作用,还有几个输入:
for _input in soup.findAll('input'):
if str(_input.attrs['name']) == 'Gender':
if str(_input.attrs['value']) == 'f':
out.write('F')
elif str(_input.attrs['value']) == 'm':
out.write('M')
else:
out.write('—')
得到此错误:
builtins.KeyError: 'name'
答案 0 :(得分:3)
对比尔的答案进行一些修改/改进:
.select_one()
代替.select()[0]
通过CSS选择器查找单个元素您不需要attrs
并使用类似字典的标记属性访问权限:
soup.select_one('#headshot img')['src']
.get_text()
is a bit more robust than accessing .text
directly
您可以改进用于获取p
元素的CSS选择器,并使用类名称以bio
开头的事实:
#vitalbox #home p[class^=bio]
您应该使用find_all()
而不是已弃用的findAll()
soup('p')
快捷方式代替soup.find_all('p')
和soup.input['value']
代替soup.find('input').attrs['value']
答案 1 :(得分:2)
select
#headshot
找到id
'headshot'的元素,img
找到带有此标记的后代元素。由于select
可能会找到元素列表,因此我们会坚持列表中的第一项,并询问元素src
属性。
>>> HTML = '''\
... <div id="headshot">
... <img title="Photo of someone" alt="Photo of somenone" src="url/file.jpg">
... </div>'''
>>> soup = bs4.BeautifulSoup(HTML, 'lxml')
>>> soup.select('#headshot img')[0].attrs['src']
'url/file.jpg'
使用findAll
标识所有p
元素,然后在列表解析中获取每个元素的文本。
>>> HTML = '''\
... <p class="bioheading">value</p>
... <div class="biodata">value</div>
... <p class="bioheading">value</p>
... <p class="biodata">value</p>
... <p class="bioheading">value</p>
... <p class="biodata"><a href"http://url.com/month=01&year=2018&day=02">January 01, 1900</a> (117 years old)</p>
... <p class="bioheading">value</p>
... <p class="biodata">value</p>
... <p class="bioheading">value</p>
... <p class="biodata">value</p>'''
>>> soup = bs4.BeautifulSoup(HTML, 'lxml')
>>> [p.text for p in soup.findAll('p')]
['value', 'value', 'value', 'value', 'January 01, 1900 (117 years old)', 'value', 'value', 'value', 'value']
如上所述,使用select
明确指定所需内容,然后在列表推导中获取文本值。
>>> HTML = '''\
... <div id="vitalbox" class="tab-content">
... <div role="tabpanel" class="tab-pane active" id="home">
... <div class="row">
... <div class="col-xs-12 col-sm-4">
... <p class="bioheading">value</p>
... <p class="biodata">value</p>
... <p class="bioheading">value</p>
... <p class="biodata">value</p>
... <p class="bioheading">value</p>
... <p class="biodata">value</p>
... </div>'''
>>> soup = bs4.BeautifulSoup(HTML, 'lxml')
>>> [p.text for p in soup.select('#vitalbox #home .row .col-xs-12 p')]
['value', 'value', 'value', 'value', 'value', 'value']
在这种情况下,只有一个元素,即input
;因此,我使用find
。由于我使用了find
(而不是产生列表的方法),我知道最多会返回一个元素。我请求它的属性。
>>> HTML = '''\
... <input name="Gender" value="m" type="hidden">'''
>>> soup = bs4.BeautifulSoup(HTML, 'lxml')
>>> soup.find('input').attrs['value']
'm'