Beautifulsoup4错误选择多个属性

Posted

技术标签:

【中文标题】Beautifulsoup4错误选择多个属性【英文标题】:Beautifulsoup4 error selecting multiple attrs 【发布时间】:2019-10-20 06:58:26 【问题描述】:

我是 bs4 的新手,我正在尝试为大学作业抓取有关亚马逊产品的一些信息,特别是我正在尝试从 html 页面中提取产品类别。我试图以这种方式提取它,但我得到一个空数组。

我需要提取:杂货和美食、糖果和巧克力、果冻豆和软糖、甘草

这是我想抓取的网页部分,但我不知道如何访问:

<div id="wayfinding-breadcrumbs_container" class="a-section a-spacing-none a-padding-medium breadcrumb-fst-exp-1 fst-breadcrumb-feature">
    <ul class="a-unordered-list a-horizontal a-size-small">
         <li><span class="a-list-item">
            <a class="a-link-normal" href="/grocery-breakfast-foods-snacks-organic/b/ref=dp_bc_aui_T1_1?ie=UTF8&node=16310101">
                Grocery & Gourmet Food
            </a>
         </span></li>
         <li><span class="a-list-item">
            <a class="a-link-normal" href="/Candy-Chocolate/b/ref=dp_bc_aui_T1_2?ie=UTF8&node=16322461">
                Candy & Chocolate
            </a>
         </span></li>
         <li><span class="a-list-item">
            <a class="a-link-normal" href="/b/ref=dp_bc_aui_T1_3?ie=UTF8&node=17369013011">
                Jelly Beans & Gummy Candy
            </a>
         </span></li>
         <li><span class="a-list-item">
            <a class="a-link-normal" href="/Licorice-Candy/b/ref=dp_bc_aui_T1_4?ie=UTF8&node=16322521">
                Licorice
            </a>
         </span></li>
    </ul>
</div>
import requests
from bs4 import BeautifulSoup
url = "https://www.amazon.com/dp/" + 'B001GVISJM'
headers = 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'
r = requests.get(url, headers=headers)
soup = BeautifulSoup(r.content, "html.parser")
for divtag in soup.find_all("div", attr="id" : "wayfinding-breadcrumbs_container"):
    print(divtag)

【问题讨论】:

类似:[a.text.strip() for a in soup.select('div#wayfinding-breadcrumbs_container ul li span a')] ? 【参考方案1】:

你可以像下面这样。对于按 id 查找,您可以将其作为函数参数传递,而不是在 attrs 中传递。

from bs4 import BeautifulSoup

t = '''
<div id="wayfinding-breadcrumbs_container" class="a-section a-spacing-none a-padding-medium breadcrumb-fst-exp-1 fst-breadcrumb-feature">
    <ul class="a-unordered-list a-horizontal a-size-small">
         <li><span class="a-list-item">
            <a class="a-link-normal" href="/grocery-breakfast-foods-snacks-organic/b/ref=dp_bc_aui_T1_1?ie=UTF8&node=16310101">
                Grocery & Gourmet Food
            </a>
         </span></li>
         <li><span class="a-list-item">
            <a class="a-link-normal" href="/Candy-Chocolate/b/ref=dp_bc_aui_T1_2?ie=UTF8&node=16322461">
                Candy & Chocolate
            </a>
         </span></li>
         <li><span class="a-list-item">
            <a class="a-link-normal" href="/b/ref=dp_bc_aui_T1_3?ie=UTF8&node=17369013011">
                Jelly Beans & Gummy Candy
            </a>
         </span></li>
         <li><span class="a-list-item">
            <a class="a-link-normal" href="/Licorice-Candy/b/ref=dp_bc_aui_T1_4?ie=UTF8&node=16322521">
                Licorice
            </a>
         </span></li>
    </ul>
</div>
'''

soup = BeautifulSoup(t, 'html.parser')
for divtag in soup.find_all(id="wayfinding-breadcrumbs_container"):
    for d in divtag.find_all(attrs='class': 'a-link-normal'):
        print(d.get_text().strip())

输出:

Grocery & Gourmet Food
Candy & Chocolate
Jelly Beans & Gummy Candy
Licorice

【讨论】:

根据我对 Q 的评论,在此处使用 .select(...) 可能更容易(并且可以说更具可读性)... 如果我考虑这个特定的 html,它可以工作,但是当我尝试从亚马逊抓取整个 html 页面时它不起作用 =( 任何想法?【参考方案2】:

短而快速的选择器(结合面包屑的 id,然后为链接键入选择器 a

categories = [item['href'] for item in soup.select('#wayfinding-breadcrumbs_feature_div a')]

【讨论】:

【参考方案3】:

试试这个:

for i in soup.find('div', id='wayfinding-breadcrumbs_container').find('ul').find_all('li', class_=None):
    text = i.find('a').text.strip()
    print(text)

for i in soup.select('#wayfinding-breadcrumbs_container a'):
    text = i.text.strip()
    print(text)

实际的亚马逊页面有另一个您没有考虑的 div。结构是:

<div>
<div> <--- missing in your post
<ul>
<li>
...

附带说明:亚马逊在抓取方面是出了名的挑剔。如果不使用计时器、代理、cookie 和冗余循环,您的爬虫将非常不一致。

【讨论】:

如何在 python 中正确设置计时器、代理、cookie 和其他我需要的东西? 此外,我应该将 r.text 或 r.content 作为 Beautifulsoup 参数传递,有什么区别? ***.com/questions/17011357/… html/xml 文档的文本和二进制类型(如图像或 pdf 文件)的内容 @StefanoSacco 没有大量代理我认为最简单的方法是使用像 proxycrawl 这样的服务。您将请求发送到他们的服务并按请求付费,但他们只向您收取成功请求的费用。显然,如果这只是一个学校项目,那么这样做是没有意义的。对于其他一切,最好的方法是使用像 Scrapy 这样的抓取框架。有一点学习曲线,但它是专门为此设计的。它可以处理标题、可变时间延迟(设置中的 AUTOTHROTTLE=True),我发现这是针对验证码的最佳措施。

以上是关于Beautifulsoup4错误选择多个属性的主要内容,如果未能解决你的问题,请参考以下文章

Python3 爬虫U11_BeautifulSoup4之select和CCS选择器提取元素

错误消息:此版本的 SQL Server 不支持对“beA2BAero.dbo.aircraft”中的数据库和/或服务器名称的引用

如何从 BeautifulSoup4 中的 html 标签中找到特定的数据属性?

Weblogic 所有BEA错误代码详细信息列表

如何使用python和beautifulsoup4循环抓取网站中多个页面的数据

Beautifulsoup4