如果您只需要只抓取特定的行,则需要在抓取它之前获取这些行。。我建议使用 str.splitlines() 和 list slice 来获取它们。
例如:
>>> import requests
>>> from bs4 import BeautifulSoup
>>> r = requests.get('http://www.yahoo.com')
>>> print('\n'.join(r.text.splitlines()[575:634]))
输出是:
<li class="D(b)">
<a href="https://www.yahoo.com/politics/" class="D(b) Fz(13px) C($topbarMenu) Py(3px) Td(n) Td(u):h" data-ylk="slk:politics;t5:politics;cpos:9;" tabindex="1">Politics</a>
</li>
<li class="D(b)">
<a href="https://www.yahoo.com/celebrity/" class="D(b) Fz(13px) C($topbarMenu) Py(3px) Td(n) Td(u):h" data-ylk="slk:celebrity;t5:celebrity;cpos:10;" tabindex="1">Celebrity</a>
</li>
...
<li class="D(b)">
<a href="https://www.yahoo.com/travel/" class="D(b) Fz(13px) C($topbarMenu) Py(3px) Td(n) Td(u):h" data-ylk="slk:travel;t5:travel;cpos:22;" tabindex="1">Travel</a>
</li>
<li class="D(b)">
<a href="https://www.yahoo.com/autos/" class="D(b) Fz(13px) C($topbarMenu) Py(3px) Td(n) Td(u):h" data-ylk="slk:autos;t5:autos;cpos:23;" tabindex="1">Autos</a>
</li>
r.text.splitlines()将HTML源代码逐行拆分,并给出一个列表。
-
[575:634] 是一个列表切片,它对列表进行切片,并给出从 576 到 634 的行。我又添加了两行,因为没有它们,输出将是:
<a href="https://www.yahoo.com/politics/" class="D(b) Fz(13px) C($topbarMenu) Py(3px) Td(n) Td(u):h" data-ylk="slk:politics;t5:politics;cpos:9;" tabindex="1">Politics</a>
</li>
<li class="D(b)">
<a href="https://www.yahoo.com/celebrity/" class="D(b) Fz(13px) C($topbarMenu) Py(3px) Td(n) Td(u):h" data-ylk="slk:celebrity;t5:celebrity;cpos:10;" tabindex="1">Celebrity</a>
</li>
...
<li class="D(b)">
<a href="https://www.yahoo.com/travel/" class="D(b) Fz(13px) C($topbarMenu) Py(3px) Td(n) Td(u):h" data-ylk="slk:travel;t5:travel;cpos:22;" tabindex="1">Travel</a>
</li>
<li class="D(b)">
<a href="https://www.yahoo.com/autos/" class="D(b) Fz(13px) C($topbarMenu) Py(3px) Td(n) Td(u):h" data-ylk="slk:autos;t5:autos;cpos:23;" tabindex="1">Autos</a>
这不是一个有效的 HTML 代码块。
'\n'.join() 通过\n 加入列表,并给出另一个你想要的字符串。
在我们有了特定的行之后:
>>> soup = BeautifulSoup('\n'.join(r.text.splitlines()[575:634]), 'html.parser')
>>> for i in soup.find_all('a'):
... print(i.get('href'))
...
...
https://www.yahoo.com/politics/
https://www.yahoo.com/celebrity/
https://www.yahoo.com/movies/
https://www.yahoo.com/music/
https://www.yahoo.com/tv/
https://www.yahoo.com/health/
https://www.yahoo.com/style/
https://www.yahoo.com/beauty/
https://www.yahoo.com/food/
https://www.yahoo.com/parenting/
https://www.yahoo.com/makers/
https://www.yahoo.com/tech/
https://shopping.yahoo.com/
https://www.yahoo.com/travel/
https://www.yahoo.com/autos/
soup.find_all('a') 在我们拥有的字符串(HTML 代码块)中找到所有<a> HTML 标签,并给出这些标签的列表。
然后,我们使用for循环遍历列表,并使用i.get('href')获取<a>标签的href属性(你想要的链接)。
您也可以使用list comprehension 将结果放入列表中,而不是打印出来:
import requests
from bs4 import BeautifulSoup
r = requests.get('http://www.yahoo.com')
soup = BeautifulSoup('\n'.join(r.text.splitlines()[575:634]), 'html.parser')
l = [i.get('href') for i in soup.find_all('a')]
l 是您要查找的列表。
如果你也想得到这些链接的title,你可以使用i.text来获取。但是,Python 中没有 table 对象,我想你的意思是 dict:
>>> d = {i.text: i.get('href') for i in soup.find_all('a')}
>>> pprint(d)
{'Autos': 'https://www.yahoo.com/autos/',
'Beauty': 'https://www.yahoo.com/beauty/',
'Celebrity': 'https://www.yahoo.com/celebrity/',
'Food': 'https://www.yahoo.com/food/',
'Health': 'https://www.yahoo.com/health/',
'Makers': 'https://www.yahoo.com/makers/',
'Movies': 'https://www.yahoo.com/movies/',
'Music': 'https://www.yahoo.com/music/',
'Parenting': 'https://www.yahoo.com/parenting/',
'Politics': 'https://www.yahoo.com/politics/',
'Shopping': 'https://shopping.yahoo.com/',
'Style': 'https://www.yahoo.com/style/',
'TV': 'https://www.yahoo.com/tv/',
'Tech': 'https://www.yahoo.com/tech/',
'Travel': 'https://www.yahoo.com/travel/'}
>>> d['TV']
'https://www.yahoo.com/tv/'
>>> d['Food']
'https://www.yahoo.com/food/'
所以你可以使用{i.text: i.get('href') for i in soup.find_all('a')} 来获取你想要的字典。
在这种情况下,i.text(标题)是该字典中的键,例如 'TV' 和 'Food'。
而i.get('href') 是值(链接),例如'https://www.yahoo.com/tv/' 和'https://www.yahoo.com/food/'。
您可以通过d[key] 访问该值,就像我上面的代码一样。