парсинг веб-сайта со страницей входа

В настоящее время я вхожу во время с веб-сайта, используя следующий скрипт.

browser = webdriver.Chrome('E:/Shared Folders/Users/runnerjp/chromedriver/chromedriver.exe')
browser.get("https://www.timeform.com/horse-racing/account/sign-in?returnUrl=%2Fhorse-racing%2F") 
time.sleep(3)
username = browser.find_element_by_id("EmailAddress")
password = browser.find_element_by_id("Password")
username.send_keys("usr")
password.send_keys("pass")
login_attempt = browser.find_element_by_xpath("//input[@type='submit']")
time.sleep(3)
login_attempt.submit()

это работает, но я обнаружил, что использование веб-драйвера Chrome загружает мой процессор. Есть ли альтернативный код, который я мог бы использовать, который не означает, что мне нужно физически загружать страницу для входа?


person emma perkins    schedule 04.06.2017    source источник


Ответы (9)


Все приведенные здесь ответы имеют определенные достоинства, но они зависят от типа очищаемого веб-сайта и способа проверки подлинности входа в систему.
Если веб-страница генерирует часть или все свое содержимое с помощью запросов javascript/ajax и т. д., то использование селена единственный путь, так как это позволяет выполнять javascript. Однако, чтобы свести использование процессора к минимуму, вы можете использовать «безголовый» браузер, такой как phantomjs. phantomjs использует тот же html-движок и движок javascript, что и chrome, поэтому вы можете протестировать свой код с помощью chrome и переключиться в конце.

Если содержимое страницы «статично», вы можете использовать модуль requests. Однако способ сделать это будет зависеть от того, использует ли веб-страница «базовую» аутентификацию, встроенную в протокол http (большинство вещей этого не делает), и в этом случае:

import requests
requests.get('https://api.github.com/user', auth=('user', 'pass'))

как предложено CodeMonkey

но если он использует что-то еще, вам придется проанализировать форму входа, чтобы увидеть, на какой адрес отправляется почтовый запрос, и создать запрос, используя этот адрес, и поместить имя пользователя/пароль в поля с идентификатором элементов на форма.

person James Kent    schedule 09.06.2017

Вместо этого используйте requests. Вы можете использовать его для входа:

import requests
requests.get('https://api.github.com/user', auth=('user', 'pass'))

Дополнительная информация здесь: http://docs.python-requests.org/en/master/user/authentication/

person CodeMonkey    schedule 07.06.2017

Вы можете использовать TestCafe.

введите здесь описание изображения

TestCafe — это бесплатная платформа с открытым исходным кодом для функционального веб-тестирования (e2e-тестирование). TestCafe основан на Node.js и вообще не использует WebDriver.

Тесты на базе TestCafe выполняются на стороне сервера. Для получения DOM-элементов TestCafe предоставляет мощную гибкую систему селекторов. TestCafe может выполнять JavaScript на тестируемой веб-странице с помощью функции ClientFunction (см. нашу документацию).

Тесты TestCafe действительно очень быстрые, убедитесь сами. Но высокая скорость тестового прогона не влияет на стабильность благодаря встроенной умной системе ожидания.

Установить TestCafe очень просто:

1) Убедитесь, что на вашем ПК установлен Node.js (или установите его).

2) Чтобы установить TestCafe, откройте cmd и введите:

npm install -g testcafe

Письменный тест — это не ракетостроение. Вот быстрый старт: 1) Скопируйте и вставьте следующий код в текстовый редактор и сохраните его как «test.js».

import { Selector } from ‘testcafe’;

fixture `Getting Started`
    .page `http://devexpress.github.io/testcafe/example`;

test(‘My first test’, async t => {
    await t
        .typeText(‘#developer-name’, ‘John Smith’)
        .click(‘#submit-button’)
        .expect(Selector(‘#article-header’).innerText).eql(‘Thank you, John Smith!‘);
});

2) Запустите тест в своем браузере (например, chrome), введя следующую команду в cmd:

testcafe chrome test.js

3) Получите описательный результат в выводе консоли.

TestCafe позволяет тестировать различные браузеры: локальные, удаленные (на устройствах, будь то браузер для Raspberry Pi или Safari для iOS), облачные (например, Sauce Labs) или безголовые (например, Nightmare). Это означает, что вы можете легко использовать TestCafe со своей инфраструктурой непрерывной интеграции.

You can use the same to scrape data and save to file easily
person Albi    schedule 14.06.2017

Использование безголового браузера будет потреблять значительно меньше ресурсов ЦП и памяти, попробуйте использовать PhantomJS настаивать на Chrome. здесь есть хороший пост в блоге об использовании PhantomJS с селеном:

https://realpython.com/blog/python/headless-selenium-testing-with-python-and-phantomjs/

person Nima Ghotbi    schedule 07.06.2017

Другой альтернативой является модуль захвата:

from grab import Grab

g = Grab()
g.go('https://www.timeform.com/horse-racing/account/sign-in?returnUrl=%2Fhorse-racing%2F')
g.doc.set_input('EmailAddress','[email protected]')
g.doc.set_input('Password','somepass')
g.doc.submit()

print g.doc.body
person brc    schedule 07.06.2017

Вы можете использовать mechanize, мне потребовалось 3,22 секунды в моем старом блокноте, чтобы войти и проанализировать сайт.

from mechanize import Browser
import time    #just to check elapsed time and check performance
started_time = time.time()

browser = Browser()
url = 'https://www.timeform.com/horse-racing/account/sign-in?returnUrl=%2Fhorse-racing%2F'
browser.open(url)
browser.select_form(nr = 0)
browser["EmailAddress"] = 'putyouremailhere'
browser["Password"] = 'p4ssw0rd'

logged = browser.submit()
redirected_url = logged.read()
print redirected_url

#you can delete this section:
elapsed_time = time.time() - started_time
print elapsed_time,' seconds'

Я надеюсь, что это помогает! :)

person Costis94    schedule 08.06.2017
comment
Трассировка (последний последний вызов): Файл E:\Shared Folders\Users\runnerjp\footballupload\Scrape timeform.py, строка 1, в ‹module› из chanize import Browser File C:\Python34\lib\site-packages\mechanize_ init_.py, строка 119, в ‹module› from _version import version ImportError: нет модуля с именем '_version' - person emma perkins; 09.06.2017
comment
Я получаю указанную выше ошибку при запуске кода - я использую python 3.4 и имею установленный механизм - person emma perkins; 09.06.2017
comment
@emmaperkins Упс! Кажется, механизация еще не поддерживает python 3.x! Проверьте это! Но вы можете запустить скрипт с определенной версией Python 2.x! - person Costis94; 12.06.2017

есть несколько способов сделать это:

  1. если вам действительно нужна вся функциональность селена (Javascript и т. д.), попробуйте использовать безголовый драйвер браузера (например, ghostdriver) однако вы не сэкономите столько процессорного времени, как если бы выбрали второй способ (ниже)
  2. вместо селена, который довольно тяжелый, вы можете использовать некоторые легкие инструменты, такие как robobrowser (py3) , механизировать или browserplus. Таким образом, вы можете сэкономить много процессорного времени, однако они не поддерживают javascript и не имеют некоторых дополнительных функций, которые есть у селена.
person internety    schedule 10.06.2017

Да, кроме селена или хрома, и, скорее, я должен сказать, кроме браузера без заголовка, вы должны использовать концепцию http (вызовы по URL-адресу).

Здесь помогут запросы и модули urllib.

Для этого необходимо определить параметры и тип метода. Как только вы определите, что необходимо для вызова URL-адреса, вы можете использовать запрос или urllib. Вам также необходимо отслеживать, какой ответ вы получаете или получите.

Вот хорошая документация по запросам.

Пример использования запросов:

Случай: здесь мы отправляем форму, которая имеет 2 поля id и pwd, метод, указанный в форме, — это post, а имена, указанные в формах, — это user_id и user_pwd для id и pwd соответственно. При нажатии кнопки он вызывает «какой-то URL»

dataToSend = {'user_id':'id you want to pass', 'user_pwd':'specify pwd here'}
# Here you can specify headers and cookie, specify if required 
response = requests.post(url, data=dataToSend, headers={'content-type':'specify if required', 'user-agent':'chrome...'})

if(response.status_code == 200):
     contentReceived = response.content
     # Here you need to observe the received content, most of the time content will be in json format, so you need to decode here.
     if(contentReceived == 'Response is same that you have expected'):
          print "Successfully"
     else:
          print "Failed"
else:
     print "Failed"

Обратитесь к другим моим ответам о том, как использовать запросы, файлы cookie и селен.

person Ujjaval Moradiya    schedule 13.06.2017

Я рекомендую вам https://scrapy.org/. Он использует скрученный под капотом, поэтому он очень эффективен.

Если вам нужно выполнить JavaScript, есть также пакет scrapy-splash: https://github.com/scrapy-plugins/scrapy-splash.

В FAQ по Scrapy есть специальная страница о страницах входа в систему: https://doc.scrapy.org/en/latest/topics/request-response.html#topics-request-response-ref-request-userlogin

person Mateusz Moneta    schedule 13.06.2017