How can I scrape a page with dynamic content (created by JavaScript) in Python?
Как я могу очистить страницу с динамическим содержимым (созданным JavaScript) в Python?
Я пытаюсь разработать простой веб-скребок. Я хочу извлекать обычный текст без HTML-разметки. Мой код работает с обычным (статическим) HTML, но не тогда, когда содержимое генерируется JavaScript, встроенным в страницу.
В частности, когда я использую urllib2.urlopen(request) для чтения содержимого страницы, оно не показывает ничего, что могло бы быть добавлено кодом JavaScript, потому что этот код нигде не выполняется. Обычно это запускается веб-браузером, но это не является частью моей программы.
Как я могу получить доступ к этому динамическому содержимому из моего кода Python?
РЕДАКТИРОВАТЬ сентябрь 2021: phantomjs также больше не поддерживается
РЕДАКТИРОВАТЬ 30 / Dec / 2017: этот ответ отображается в лучших результатах поиска Google, поэтому я решил его обновить. Старый ответ все еще находится в конце.
dryscape больше не поддерживается, и разработчики dryscape рекомендуют использовать только библиотеку Python 2. Я обнаружил, что использование библиотеки python от Selenium с Phantom JS в качестве веб-драйвера достаточно быстро и просто для выполнения работы.
После установки Phantom JS убедитесь, что phantomjs двоичный файл доступен по текущему пути:
phantomjs --version # result: 2.1.1
# Пример Чтобы привести пример, я создал пример страницы со следующим HTML-кодом. (ссылка):
Мы не получаем правильных результатов, потому что любое содержимое, сгенерированное javascript, должно быть отображено в DOM. Когда мы извлекаем HTML-страницу, мы извлекаем начальный, неизмененный javascript, DOM.
Поэтому нам нужно отобразить содержимое javascript перед обходом страницы.
Поскольку selenium уже много раз упоминается в этой теме (и также упоминалось, насколько медленно он иногда работает), я перечислю два других возможных решения.
На нашем компьютере установленDocker. До этого момента это было плюсом по сравнению с другими решениями, поскольку оно использует платформу, независимую от операционной системы.
Установите Splash, следуя инструкции, указанной для нашей соответствующей ОС. Цитирую документацию splash:
Splash - это служба рендеринга javascript. Это легкий веб-браузер с HTTP API, реализованный на Python 3 с использованием Twisted и QT5.
По сути, мы собираемся использовать Splash для рендеринга содержимого, сгенерированного Javascript.
Запустите сервер splash: sudo docker run -p 8050:8050 scrapinghub/splash.
В обычном spider у вас есть объекты запроса, которые вы можете использовать для открытия URL-адресов. Если страница, которую вы хотите открыть, содержит данные, сгенерированные JS, вы должны использовать SplashRequest (или SplashFormRequest) для рендеринга страницы. Вот простой пример.:
classMySpider(scrapy.Spider): name = "jsscraper" start_urls = ["http://quotes.toscrape.com/js/"]
defstart_requests(self): for url inself.start_urls: yield SplashRequest( url=url, callback=self.parse, endpoint='render.html' )
defparse(self, response): for q in response.css("div.quote"): quote = QuoteItem() quote["author"] = q.css(".author::text").extract_first() quote["quote"] = q.css(".text::text").extract_first() yield quote
SplashRequest отображает URL-адрес в виде html и возвращает ответ, который вы можете использовать в методе обратного вызова (parse).
Решение 2: На данный момент (май 2018 г.) давайте назовем это экспериментальным...
Это решение предназначено только для Python версии 3.6 (на данный момент).
Вы знаете модуль requests (а кто его не знает)? Теперь у него есть младший брат для обхода веб-страниц: requests-HTML:
Эта библиотека предназначена для того, чтобы сделать синтаксический анализ HTML (например, очистить веб) максимально простым и интуитивно понятным.
Запросы на установку-html: pipenv install requests-html
Сделайте запрос к URL страницы:
from requests_html import HTMLSession
session = HTMLSession() r = session.get(a_page_url)
Визуализируйте ответ, чтобы получить сгенерированные Javascript биты:
В качестве альтернативы мы можем попробовать хорошо документированный способ использования BeautifulSoup с r.html объектом, который мы только что визуализировали.
Если вы когда-либо раньше использовали Requests модуль для python, я недавно узнал, что разработчик создал новый модуль под названием Requests-HTML который теперь также имеет возможность отображать JavaScript.
По сути, после правильной установки Requests-HTML модуля следующий пример, который показан по ссылке выше, показывает, как вы можете использовать этот модуль для очистки веб-сайта и визуализации JavaScript, содержащегося на веб-сайте:
from requests_html import HTMLSession session = HTMLSession()
r = session.get('http://python-requests.org/')
r.html.render()
r.html.search('Python 2 will retire in only {months} months!')['months']
'<time>25</time>'#This is the result.
Недавно я узнал об этом из видео на YouTube. Нажмите здесь! чтобы посмотреть видео на YouTube, в котором демонстрируется, как работает модуль.