Beautifulsoup返回不完整的HTML

时间:2017-01-17 20:23:51

标签: python parsing beautifulsoup flickr

我正在读一本关于Python的书。家庭作业有一个小项目: "编写一个程序,进入像Flickr或Imgur这样的照片共享网站,搜索一类照片,然后下载所有生成的图像。" 建议仅使用webbrowser,requests和bs4库。

我无法为Flickr做到这一点。我发现解析器不能进入元素内部(div class =" interaction-view")。使用"检查元素"在Chrome中我可以看到有一些" div"里面的元素和" a"元件。但是,当我使用bs4库时,它无法看到它。

我的代码是这样的:

#!/usr/bin/env python3
# To download photos from Flickr

import requests, bs4

search_name = "spam"
website_name = requests.get('https://www.flickr.com/search/?text='
                       + search_name)
website_name.raise_for_status()
parse_obj = bs4.BeautifulSoup(website_name.text, "html.parser")
elements = parse_obj.select('body #content main .main.search-photos-results \
                .view.photo-list-view.requiredToShowOnServer \
                .view.photo-list-photo-view.requiredToShowOnServer.awake \
                .interaction-view')
print(elements)

它只打印:

[<div class="interaction-view"></div>, <div class="interaction-view"></div>...]

没有任何嵌套元素,我不明白为什么...... 谢谢!

1 个答案:

答案 0 :(得分:4)

问题是flickr上<div class="interaction-view"></div>的内容只能通过javascript加载。您可以检查,如果您查看了网页来源,则会在div标签中找不到内容<div class="interaction-view"></div>

你需要以某种方式执行javascript。由于beautifulsoup没有提供这个,一个解决方案是使用硒。 pip install selenium并为firefox安装geckodriver(在OSX上:brew install geckodriver)。然后更改代码以使用selenium加载页面:

#!/usr/bin/env python3

import requests, bs4
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

search_name = "spam"
url = 'https://www.flickr.com/search/?text=%s' % search_name

browser = webdriver.Firefox()
browser.get(url)
delay = 3
WebDriverWait(browser, delay).until(EC.presence_of_element_located(browser.find_element_by_id('...')))

soup = bs4.BeautifulSoup(browser.page_source, "html.parser")


elements = soup.select('body #content main .main.search-photos-results \
                .view.photo-list-view.requiredToShowOnServer \
                .view.photo-list-photo-view.requiredToShowOnServer.awake \
                .interaction-view')
print(elements)

需要WebDriverWait部分,因此selenium会等待解析,直到加载某个元素。您需要将...更改为您知道将出现的ID。请参阅this answer以查看如何使用类完成。