2017-01-17 7 views
1

Я читаю книгу о Python прямо сейчас. Существует небольшой проект для домашней работы: «Напишите программу, которая отправляется на сайт для обмена фотографиями, такой как Flickr или Imgur, ищет категорию фотографий, а затем загружает все результирующие изображения». Предлагается использовать только библиотеки веб-браузера, запросов и библиотек bs4.Beautifulsoup возвращает неполный html

Я не могу сделать это для Flickr. Я обнаружил, что анализатор не может войти внутрь элемента (div class = "взаимодействие-view"). Используя «Inspect element» в 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>...] 

Без каких-либо вложенных элементов, и я не понимаю, почему ... Спасибо!

+0

Вы можете исправить блок кода? первая строка должна быть '#!/usr/bin/env python3', а затем' Soup.select' должен быть 'parse_obj.select'. Это позволяет людям воспроизводить – hansaplast

+0

Готово. Спасибо. – Trarbish

ответ

4

Проблема заключается в том, что содержимое <div class="interaction-view"></div> на flickr загружается только через javascript. Вы можете проверить, что если вы просмотрите источник страницы, вы найдете: <div class="interaction-view"></div> без содержимого в теге div.

Вам нужно каким-то образом выполнить javascript. Поскольку beautifulsoup не предлагает этого, одно из решений - использовать для этого селен. pip install selenium и установите geckodriver для firefox (на 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 часть необходима так селен ждет с разбором, пока не будет загружен определенный элемент. Вам нужно изменить ... на идентификатор, который, как вы знаете, будет присутствовать. См. this answer, чтобы проверить, как это можно сделать с помощью классов.

+0

Интересно, спасибо! Я обнаружил, что перед созданием объекта BeautifulSoup необходимо добавить паузу (например, time.sleep (5)). В противном случае я не получаю «заполненный» список. Правильно ли я понимаю: 1) когда я «проверяю элемент» в браузере Я запускаю код JavaScript и вижу «заполненный» div? 2) Когда я просто нажимаю F12, я не запускаю код JavaScript. В результате в теге div нет содержимого? – Trarbish

+0

хорошо пункт. Сначала вам нужно дождаться появления определенного элемента, я обновил свой ответ. 'sleep', вероятно, работает, но слишком долго ждет, если загрузка будет быстрой или может завершиться неудачей, если загрузка будет медленной, лучше перейдите на страницу' WebDriverWait' – hansaplast

+0

'F12' открывает консоль разработчика. Это не то же самое, что и источник html. То, что beautifulsoup видит при выполнении 'request.get', вы видите, когда щелкните правой кнопкой мыши-> просмотр источника. То, что видит селен, - это то, что вы делаете в консоли разработчика (например, при запуске '$ (" body #content ... ")) – hansaplast