Я хочу стянуть информацию с сайта. Как это сделать?

Дмитрий

5-й уровень

Допустим, нам нужно получить данные с сайта, сбор которых вручную нецелесообразен или невозможен из-за объёма. В таком случае мы можем автоматизировать процесс, используя инструменты, описанные далее.

Библиотека requests

Python-библиотека для выполнения запросов к серверу и обработки ответов. Фундамент скрипта для парсинга и наше основное оружие. Пользуясь данной библиотекой мы получаем содержимое страницы в виде html для дальнейшего парсинга.

import requests

response = requests.get('https://ya.ru') # get-запрос
print(response.text) # вывод содержимого страницы

payload = {'key1': 'value1', 'key2': 'value2'}
response = requests.get('http://httpbin.org/get', params=payload) # запрос с параметрами

headers = {'user-agent': 'my-app/0.0.1'} 
response = requests.get(url, headers=headers) # запрос с определенными html заголовками

Документация: http://docs.python-requests.org/en/master/user/quickstart/

API

Application programming interface - программный интерфейс приложения, предоставляемый владельцем веб-приложения для других разработчиков. Отсутствие API, способного удовлетворить наши нужды - первое в чем стоит убедиться прежде чем бросаться анализировать исходный код страницы и писать для нее парсер. Множество популярных сайтов имеет собственное api и документацию, которая объясняет как им пользоваться. Мы можем использовать api таким образом - формируем http-запрос согласно документации, и получаем ответ при помощи requests.

BS4

Beautifulsoup4 - это библиотека для парсинга html и xml документов. Позволяет получить доступ напрямую к содержимому любых тегов в html.

from bs4 import BeautifulSoup

soup = BeautifulSoup(raw_html, 'html.parser')
print(soup.find("p", class_="some-class").text) # вывод содержимого тэга 'p' классом 'some-class'

Подробная документация: https://www.crummy.com/software/BeautifulSoup/bs4/doc/

Selenium Web Driver

Данные на сайте могут генерироваться динамически при помощи javascript. В таком случае спарсить эти данные силами requests+bs4 не удастся. Дело в том, что bs4 парсит исходный код страницы, не исполняя js. Для исполнения js кода и получения страницы, идентичной той, которую мы видим в браузере, можно использовать selenium web driver - это набор драйверов для различных браузеров, снабжающийся библиотеками для работы с этими драйверами.

Большой туториал по парсингу: http://thiagomarzagao.com/2013/11/12/webscraping-with-selenium-part-1/

А что делать, если там авторизация?

Предварительно авторизоваться, отправив post-запрос и инициировать сессию:

session = requests.Session()
data = {"login_username":"login", "login_password":"password"}
url = "http://site.com/login.php"
response = session.post(url, data=data)

А что, если сайт банит за много запросов?

  • Установить задержку между запросами:
response = requests.get(url, timeout=(10, 0.01)) # таймаут на соединения, таймаут на чтение (в секундах)
  • Притвориться браузером, используя selenium web driver или передав содержимое заголовка user-agent, формируя запрос:
user_agent = ('Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:50.0) '
              'Gecko/20100101 Firefox/50.0')
request = requests.get(url, headers={'User-Agent':user_agent})
  • Использовать прокси:
request = requests.get(url, proxies={"http":"http://10.10.1.10:3128"})