使用 BeautifulSoup 从维基百科获取特定图像
Getting a particular image from Wikipedia with BeautifulSoup
我试图通过使用 BeautifulSoup 4 和 lxml 作为解析器从某些维基百科页面获取特定图像。例如,我正在尝试从此维基百科页面获取右侧的专辑封面:
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>
我要拉出的图片是<a class...
开头的第二块图片,不是第一块
里的书本图片
我想在这里完成的是:
我只想获取 src
指定的链接,而不是 class 附带的所有链接。
我希望能够区分书本图像和我要拉出的图像。书的图片在那里,因为如果你查看维基百科页面,它说这篇文章需要引用,那里有一张书的图片。显然它符合我对标签 a
和 class image
的搜索,但它可能存在也可能不存在,具体取决于相关文章。
怎样才能只得到我感兴趣的图片,也就是文章右边的图片?
好吧,你已经得到了你想要的 99%,所以这是最主要的。我的第一个想法是收紧你的过滤器一点点。如果这是一个一次性的案例,并且你不需要在很多地方应用这个程序,BeautifulSoup.find_all() 中的 'text' 参数可能会帮助你:
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
您的搜索不够具体。图书图像嵌套在元数据 table:
中
<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
属性的 <img>
标签,前提是它们嵌套在 <a class="image">
元素中,位于 <table class="infobox">
元素内.只有一张这样的图片:
>>> 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
我试图通过使用 BeautifulSoup 4 和 lxml 作为解析器从某些维基百科页面获取特定图像。例如,我正在尝试从此维基百科页面获取右侧的专辑封面: 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>
我要拉出的图片是<a class...
开头的第二块图片,不是第一块
我想在这里完成的是:
我只想获取
src
指定的链接,而不是 class 附带的所有链接。我希望能够区分书本图像和我要拉出的图像。书的图片在那里,因为如果你查看维基百科页面,它说这篇文章需要引用,那里有一张书的图片。显然它符合我对标签
a
和 classimage
的搜索,但它可能存在也可能不存在,具体取决于相关文章。
怎样才能只得到我感兴趣的图片,也就是文章右边的图片?
好吧,你已经得到了你想要的 99%,所以这是最主要的。我的第一个想法是收紧你的过滤器一点点。如果这是一个一次性的案例,并且你不需要在很多地方应用这个程序,BeautifulSoup.find_all() 中的 'text' 参数可能会帮助你:
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
您的搜索不够具体。图书图像嵌套在元数据 table:
中<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
属性的 <img>
标签,前提是它们嵌套在 <a class="image">
元素中,位于 <table class="infobox">
元素内.只有一张这样的图片:
>>> 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