2017-01-17 75 views
1

我正在讀一本關於Python的書。有一個小作業: 「編寫一個程序,轉到像Flickr或Imgur這樣的照片分享網站,搜索一類照片,然後下載所有最終的圖像。」 建議只使用網頁瀏覽器,請求和bs4庫。Beautifulsoup返回不完整的html

我不能爲Flickr做到這一點。我發現解析器不能進入元素(div class =「interaction-view」)。在Chrome中使用「Inspect元素」我可以看到裏面有幾個「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>...] 

沒有任何嵌套元素,我不明白爲什麼... 謝謝!

+0

你能改正代碼塊嗎?第一行應該是'#!/ usr/bin/env python3',然後'Soup.select'應該是'parse_obj.select'。這使得人們更容易重現 – hansaplast

+0

完成。謝謝。 – Trarbish

回答

4

問題是,flickr上的<div class="interaction-view"></div>的內容只能通過javascript加載。您可以檢查,如果您查看頁面源代碼,您會發現:<div class="interaction-view"></div> div標籤中沒有內容。

你需要以某種方式執行JavaScript。由於美麗的臉不提供這一點,一個解決方案是使用硒。 pip install selenium並安裝用於Firefox的geckodriver(在OSX上:brew install geckodriver)。然後改變你的代碼,使用硒加載頁面:需要

#!/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一部分,所以硒,直到某個元素加載解析等待。您需要將...更改爲您知道會出席的ID。請參閱this answer以檢查如何使用類完成此操作。

+0

有趣,謝謝!我發現它需要在創建BeautifulSoup對象之前添加暫停(例如time.sleep(5))。否則,我不會收到「填充」列表。 我的理解是否正確: 1)當我在瀏覽器中「檢查元素」時,我運行JavaScript代碼並可以看到「填充」div? 2)當我只按F12我不運行JavaScript代碼。因此,div標籤中沒有內容? – Trarbish

+0

好點。你首先需要等待某個元素出現,然後我更新了答案。 '睡眠'可能有效,但如果加載速度很快或者如果加載速度很慢可能會失敗,則等待時間過長,最好使用'WebDriverWait'方法 – hansaplast

+0

'F12'打開開發者控制檯。這與html源碼不一樣。當右鍵單擊 - >查看源代碼時,執行'requests.get'時會看到什麼美麗的東西。無論你在開發者控制檯中做什麼(例如,當你運行'$(「body #content ...」)') – hansaplast