【问题标题】:Getting a particular image from Wikipedia with BeautifulSoup使用 BeautifulSoup 从 Wikipedia 获取特定图像
【发布时间】:2015-03-16 09:35:27
【问题描述】:

我正在尝试通过使用带有 lxml 作为解析器的 BeautifulSoup 4 从一些 Wikipedia 页面获取特定图像。例如,我试图从这个维基百科页面获取右边的专辑封面: http://en.wikipedia.org/wiki/Animal_House_(U.D.O._album)

执行抓取的函数是这样的:

def get_cover_from_wikipedia(url):
    r = requests.get(url)
    if r.status_code == 200:
        soup = BeautifulSoup(r.content, 'lxml')
        elements = soup.find_all('a', class_='image')
        for element in elements:
            print '%s\n\n' % element.prettify()

    return False

打印的输出如下:

<a class="image" href="/wiki/File:Question_book-new.svg">
 <img alt="" data-file-height="204" data-file-width="262" height="39" src="//upload.wikimedia.org/wikipedia/en/thumb/9/99/Question_book-new.svg/50px-Question_book-new.svg.png" srcset="//upload.wikimedia.org/wikipedia/en/thumb/9/99/Question_book-new.svg/75px-Question_book-new.svg.png 1.5x, //upload.wikimedia.org/wikipedia/en/thumb/9/99/Question_book-new.svg/100px-Question_book-new.svg.png 2x" width="50"/>
</a>

<a class="image" href="/wiki/File:UDO_animal_house.jpg">
 <img alt="" data-file-height="302" data-file-width="300" height="221" src="//upload.wikimedia.org/wikipedia/en/thumb/4/4e/UDO_animal_house.jpg/220px-UDO_animal_house.jpg" srcset="//upload.wikimedia.org/wikipedia/en/4/4e/UDO_animal_house.jpg 1.5x, //upload.wikimedia.org/wikipedia/en/4/4e/UDO_animal_house.jpg 2x" width="220"/>
</a>

我要提取的图像是第二个块中以&lt;a class... 开头的图像,而不是第一个块中的图像的书图像

我想在这里完成的是:

  1. 我只想获取src 指定的链接,而不是类附带的所有内容。

  2. 我希望能够区分图书图像和我要拉出的图像。书籍图片在那里,因为如果您查看 Wikipedia 页面,它会说文章需要引用,并且那里有书籍图片。显然它与我对标签 a 和类 image 的搜索匹配,但它可能存在也可能不存在,具体取决于相关文章。

仅获取我感兴趣的图像(即文章右侧的图像)的最佳方法是什么?

【问题讨论】:

    标签: python html css web-scraping beautifulsoup


    【解决方案1】:

    您的搜索不够具体。图书图像嵌套在元数据表中:

    <table class="metadata plainlinks ambox ambox-content ambox-Refimprove" role="presentation">
    

    当专辑封面嵌套在另一个中时:

    <table class="infobox vevent haudio" style="width:22em">
    

    利用它来发挥你的优势。

    使用CSS selector support 使这变得微不足道:

    covers = soup.select('table.infobox a.image img[src]')
    for cover in covers:
        print cover['src']
    

    CSS 选择器要求带有src 属性的&lt;img&gt; 标签,前提是它们嵌套在&lt;a class="image"&gt; 元素中,在&lt;table class="infobox"&gt; 元素中。只有一张这样的图片:

    >>> from bs4 import BeautifulSoup
    >>> import requests
    >>> r = requests.get('http://en.wikipedia.org/wiki/Animal_House_(U.D.O._album)')
    >>> soup = BeautifulSoup(r.content)
    >>> covers = soup.select('table.infobox a.image img[src]')
    >>> for cover in covers:
    ...     print cover['src']
    ... 
    //upload.wikimedia.org/wikipedia/en/thumb/4/4e/UDO_animal_house.jpg/220px-UDO_animal_house.jpg
    

    【讨论】:

    • 您一定会喜欢那些比您要求的更多教给您的答案。非常感谢!
    【解决方案2】:

    嗯,你已经得到了你想要的 99%,所以这是最重要的。我的第一个想法是稍微收紧过滤器。如果这是一次性案例,并且您不需要在很多地方应用此程序,BeautifulSoup.find_all() 中的“文本”参数可能会对您有所帮助:

    if r.status_code == 200:
        soup = BeautifulSoup(r.content, 'lxml')
        elements = soup.find_all('a', text='.jpg' class_='image')
        for element in 
            print '%s\n\n' % element.prettify()
    
    return False
    

    由于您的目标图像是页面上唯一的 .jpg 文件,这应该会有所帮助。您可能已经看过了,但是如果您遇到困难,这应该会有所帮助: http://www.crummy.com/software/BeautifulSoup/bs4/doc/#find-all

    【讨论】:

    • text 带字符串值只能匹配子文本节点整个文本。例如。您现在正在搜索&lt;a class="image"&gt;.jpg&lt;/a&gt; 之类的标签,其中标签除了image 之外还可以有其他属性或其他类,但没有其他嵌套标签,更不用说偏离.jpg 的文本了,确切地。您必须使用正则表达式对象并搜索 img 标记及其 src 属性。
    猜你喜欢
    • 1970-01-01
    • 2016-03-19
    • 2020-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-24
    相关资源
    最近更新 更多