Программно загружать текст, который не отображается в источнике страницы
Я пишу сканер на Python. Учитывая одну веб-страницу, я извлекаю это Html
содержание следующим образом:
import urllib2
response = urllib2.urlopen('http://www.example.com/')
html = response.read()
Но некоторые текстовые компоненты не отображаются в источнике HTML-страницы, например, на этой странице (перенаправлены на указатель, перейдите к одной из дат и просмотрите конкретную почту), если вы просматриваете источник страницы, вы увидите, что текст письма не не появляется в источнике, но, кажется, загружен JS.
Как я могу программно загрузить этот текст?
3 ответа
Здесь проще всего сделать запрос POST к URL-адресу, отвечающему за поиск по электронной почте, и проанализировать результаты JSON (с упоминанием @recursive, поскольку он первым предложил эту идею). Пример использования requests
пакет:
import requests
data = {
'year': '1999',
'month': '05',
'day': '20',
'locale': 'en-us'
}
response = requests.post('http://jebbushemails.com/api/email.py', data=data)
results = response.json()
for email in results['emails']:
print email['dateCentral'], email['subject']
Печать:
1999-05-20T00:48:23-05:00 Re: FW: The Reason Study of Rail Transportation in Hillsborough
1999-05-20T04:07:26-05:00 Escambia County School Board
1999-05-20T06:29:23-05:00 RE: Escambia County School Board
...
1999-05-20T22:56:16-05:00 RE: School Board
1999-05-20T22:56:19-05:00 RE: Emergency Supplemental just passed 64-36
1999-05-20T22:59:32-05:00 RE:
1999-05-20T22:59:33-05:00 RE: (no subject)
Другой подход заключается в том, чтобы позволить настоящему браузеру обрабатывать динамическую часть страницы, загружаемую через JavaScript, с помощью selenium
рамки автоматизации браузера:
# -*- coding: utf-8 -*-
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome() # can also be, for example, webdriver.Firefox()
driver.get('http://jebbushemails.com/email/search')
# click 1999-2000
button = driver.find_element_by_xpath('//button[contains(., "1999 – 2000")]')
button.click()
# click 20
cell = driver.find_element_by_xpath('//table[@role="grid"]//span[. = "20"]')
cell.click()
# click Submit
submit = driver.find_element_by_xpath('//button[span[1]/text() = "Submit"]')
submit.click()
# wait for result to appear
WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, "//tr[@analytics-event]")))
# get the results
for row in driver.find_elements_by_xpath('//tr[@analytics-event]'):
date, subject = row.find_elements_by_tag_name('td')
print date.text, subject.text
Печать:
6:24:27am Fw: Support Coordination
6:26:18am Last nights meeting
6:52:16am RE: Support Coordination
7:09:54am St. Pete Times article
8:05:35am semis on the interstate
...
6:07:25pm Re: Appointment
6:18:07pm Re: Mayor Hood
8:13:05pm Re: Support Coordination
Обратите внимание, что браузер здесь также может быть безголовым, как PhantomJS
, И, если нет браузера для работы браузера - вы можете запустить виртуальный, посмотрите примеры здесь:
Вы можете сделать запрос к фактической службе AJAX, вместо того, чтобы пытаться использовать веб-интерфейс.
Например, почтовый запрос к http://jebbushemails.com/api/email.py с данными этой формы даст 80 КБ легко разбираемого json.
year:1999
month:05
day:20
locale:en-us
Я не эксперт по Python, но любая функция, такая как urlopen, получает статический HTML, а не выполняет его. Что вам нужно, так это какой-то движок браузера, чтобы фактически анализировать и выполнять JavaScript. Кажется, здесь ответили:
Как разобрать Java-скрипт, содержащий [dynamic] на веб-странице [html] с использованием Python?