【问题标题】:Web Scraping a List in Python Using BeautifulSoup使用 BeautifulSoup 在 Python 中 Web 抓取列表
【发布时间】:2016-02-09 02:15:08
【问题描述】:

我是 Python 新手,正在尝试学习如何使用 BeautifulSoup 来抓取网页。对于初学者,我只是使用 yahoo.com 的 HTML 代码:

查看源代码:https://www.yahoo.com/

我想抓取从第 577 行开始到 633 结束的链接列表,并获取它们的 URL 和标题并将其放在 Python 中的表中。

到目前为止,我有以下内容:

from bs4 import BeautifulSoup

myURL = "http://www.yahoo.com"
myPage = requests.get(myURL)

yahoo = BeautifulSoup(myPage.content)

print yahoo.prettify()

YahooList = yahoo.find('ul', class_="Pos(r) Miw(1000px) Pstart(9px) Lh(1.7) Reader-open_Op(0) mini-header_Op(0)")
print YahooList

我不确定如何进一步处理。我发现的所有示例都是从表格中抓取网络的,但我在列表中找不到太多关于如何执行此操作的示例。

有人有什么建议吗?

谢谢, 尼克

【问题讨论】:

  • 我想抓取从第 577 行开始到第 633 行结束的链接列表 是什么意思?您的意思是从 HTML 源代码的 577 行到 633 行中的所有链接
  • 是的,这正是我的意思。从整个网页中,我只想抓取那些特定的行。如果我的帖子中不清楚,我深表歉意。
  • myURL, YahooList 这样的变量名称不是 Pythonic,PEP-8 推荐的名称是 my_urlyahoo_list 等。

标签: python beautifulsoup yahoo


【解决方案1】:

如果您只需要只抓取特定的行,则需要在抓取它之前获取这些行。我建议使用 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] 是一个列表切片,它对列表进行切片,并给出从 576634 的行。我又添加了两行,因为没有它们,输出将是:

        <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 代码块)中找到所有&lt;a&gt; HTML 标签,并给出这些标签的列表。

然后,我们使用for循环遍历列表,并使用i.get('href')获取&lt;a&gt;标签的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] 访问该值,就像我上面的代码一样。

【讨论】:

    猜你喜欢
    • 2018-12-09
    • 2019-06-28
    • 2013-09-28
    • 1970-01-01
    • 2018-06-11
    • 1970-01-01
    • 1970-01-01
    • 2018-10-06
    • 1970-01-01
    相关资源
    最近更新 更多