【问题标题】:Beautiful Soup | How to separate multiple attrs within <a> tags美丽的汤|如何在 <a> 标签中分隔多个属性
【发布时间】:2018-09-21 04:25:44
【问题描述】:

我正在尝试抓取网页以收集图像名称及其各自的资产 URL,并将它们写入 CSV 中的两个单独列。我无法将 attrs 从标签中分离出来。

在 BS4 中,我可以运行:

soup.find_all('a')

成功返回下面的html(乘以页面上的照片数)

<a aria-label="SomeImageName" data-asset-id="10101010101" 
href="SomeWebsite">
<img alt="SomeImageName" 
src="https://SomeImageUrl"/>
</a>

我已尝试运行以下(以及许多其他变体)

soup.find_all('a', attrs{"aria-label", "src"})

他们回来了

[]

有人知道如何从标签中提取这些数据并写入 CSV 吗?

干杯!

【问题讨论】:

    标签: python web-scraping beautifulsoup


    【解决方案1】:

    欢迎来到 StackOverflow! 您对两个不同的元素有您的要求,即a 中的aria-labelimg 中的src。但幸运的是,img 嵌套在 a 标记内。所以迭代会很简单。

    将名称和链接存储在字典列表中,使用DictWriter(),您可以轻松地将它们写入 csv 文件。

    import csv
    img_data = []
    for a_tag in soup.find_all('a'):
        data_dict = dict()
        data_dict['image_name'] = a_tag['aria-label']
        data_dict['url'] = a_tag.img['src']
        img_data.append(data_dict)
    
    with open('urls.csv', 'w') as csvfile:
        fieldnames = ['image_name', 'url']
        writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
        writer.writeheader()
        for data in img_data:    
            writer.writerow(data)
    

    希望这会有所帮助!干杯!

    【讨论】:

    • 感谢您的回复!不过仍然有问题 - 似乎它没有收到aria-label。这是我在第 4 行遇到的错误 KeyError: 'aria-label' 想法?
    • 您的某些标签似乎没有aria-label 属性。您可以通过try except 或以下代码data_dict['image_name'] = a_tag['aria-label'] if 'aria-label' in str(a_tag) else '' 处理。如果缺少该属性,后者将添加一个空字符串,而第一个将跳过没有该属性的块。 P.S.:if else 是一个单行,你可以像这样添加它。
    • 太棒了,它看起来像已修复的部分,现在出现与 Hari 示例中相同的错误 - TypeError: 'NoneType' object is not subscriptable 在线包含 data_dict['url'] = a_tag.img['src'] - 我现在将对这个错误进行一些研究。你知道修复吗? ((看起来这些是 BS 的一些非常常见的问题。这是我第一次使用。感谢十亿的帮助!)
    • 如果还有其他类似的,只需添加。但是条件必须检查那里是否存在img 标签。像if a_tag.img else '' 这样的东西。而不是感谢,而是对我的回答投赞成票,这将激励我更多地分享知识。
    • 谢谢@SmashGuy 我让它工作了。如果你想看看我最终做了什么,我发布了一个答案!
    【解决方案2】:

    试试下面的代码,它提取&lt;a&gt;标签内的&lt;img&gt;标签的src属性的值,该标签具有aria-label属性,并将这些链接写入一个csv文件

    ## To get the value of src attribute in the <img> tag
    tags = soup.find_all('a')
    src=[]
    for tag in tags:
        if tag.has_attr('aria-label'):
            src.append(tag.img['src'])
    
    ##writing to a csv file
    with open('csvfile.csv','w') as file:
        for line in src:
            file.write(line)
            file.write('\n')
    

    或者你可以使用csv模块写入数据

    import csv
    with open('csvfile1.csv', "w",newline='') as csv_file:
        writer = csv.writer(csv_file)
        writer.writerow(src)
    

    【讨论】:

    • find_all 为什么不使用csv 模块?
    • @G_M,find_all()findAll()有什么区别?
    • @SmashGuy 链接已提供... BeautifulSoup 3 vs 4
    • 感谢@Hari 的回复!但是我确实遇到了这个错误:TypeError Traceback (most recent call last) &lt;ipython-input-199-9ab36d053c0c&gt; in &lt;module&gt;() 3 for tag in tags: 4 if tag.has_attr('aria-label'): ----&gt; 5 src.append(tag.img['src']) TypeError: 'NoneType' object is not subscriptable Thoughts?
    【解决方案3】:

    感谢大家的投入!我仍然无法拉出aria-label,并且我在其他一些论坛上看到这是解析 HTML 时出现的 BS4 问题。

    然而,我能够使用@SmashGuy 解决方案很容易地解决这个问题,并将替代文本描述与aria-label 拉开。

    img_data = []
    for img_tag in soup.find_all('img'):
        data_dict = dict()
        data_dict['image_name'] = img_tag['alt']
        data_dict['image_url'] = img_tag['src']
        img_data.append(data_dict)
    

    然后写入 CSV...

    with open('BCDS1.csv', 'w', newline='') as birddata:
        fieldnames = ['image_name', 'image_url']
        writer = csv.DictWriter(birddata, fieldnames=fieldnames)
        writer.writeheader()
        for data in img_data:
            writer.writerow(data)
    

    再次感谢大家的帮助!干杯!

    【讨论】:

      【解决方案4】:

      对于需要找到&lt;img&gt; 标记的图像,&lt;a&gt; 是链接标记。

      <a aria-label="SomeImageName" data-asset-id="10101010101" href="SomeWebsite">
          <img alt="SomeImageName" src="https://SomeImageUrl"/>
      </a>
      

      您找到了该图像,因为如您所见,链接标签包裹了图像标签。

      这不是字典语法的工作方式,请在attrs={} 中使用:(参见https://www.crummy.com/software/BeautifulSoup/bs4/doc/#the-keyword-arguments

      所以它是soup.find_all('a', attrs={'css': 'value'}) 而不是soup.find_all('a', attrs{"aria-label" "SomeImageName"})

      猜你喜欢
      • 1970-01-01
      • 2021-09-18
      • 1970-01-01
      • 2020-06-25
      • 2021-12-07
      • 2018-07-18
      • 1970-01-01
      • 1970-01-01
      • 2021-08-26
      相关资源
      最近更新 更多