Cкачивание данных с сайтов защищенных от роботов (Python)

Для построения моделей в нейронных сетях нужны большие объемы данных. Нередко они тщательно охраняются владельцами и просто так их не получить. Когда данные нужны в коммерческих целях — можно и заплатить. Но если они нужны для решения образовательных задач, то платить не очень хочется. Например, на сайте bloomberg неплохая защита от ботов. Простые способы не проходят. Точнее говоря самый простой — это использовать браузер и забирать контент чере него. В этом случае данные отдаются нормально, хотя даже их иногда bloomberg принимает за робота и просит ввести Captcha.

Если данные для парсинга берутся скриптом на python для тренировки нейронной сети, то хотелось бы с помощью него и забирать данные с сайта. Простые способы обхода, вроде того, чтобы в header передать в user-agent адекватную строчку или GoogleBot — не прокатывают. Тот-же bloomberg без проблем вычисляет, собственно для этого достаточно c их стороны использовать cookie и/или JavaScript, поскольку обычный Python скрипт только забирает данные. Для обхода ограничений используются различные способы эмуляции работы браузера, но без отображаения GUI.

Это мои заметки по теме по мере сбора данных, пока что не законченная статья. Если есть, что сказать — пишите на почту или в комментарии.

WebKit + Python

Самый простой способ — использовать в Python браузерный движок WebKit. Python поддерживает установку модулей WebKit через pip.

pip install PyQt5
или
pip install pyqtwebengine

Пример скрипта на PyQt5:

import sys
from PyQt5 import QtWebKit
from PyQt5 import QtCore
from PyQt5 import QtGui

class Render(QtWebKit.QWebPage):
    def __init__(self, url):
        self.app = QtGui.QApplication(sys.argv)
        QtWebKit.QWebPage.__init__(self)
        self.loadFinished.connect(self._loadFinished)
        self.mainFrame().load(QtCore.QUrl(url))
        self.app.exec_()

    def _loadFinished(self, result):
        self.frame = self.mainFrame()
        self.app.quit()

url = 'http://www.scoreboard.com/game/6LeqhPJd/#game-summary'
r = Render(url)
content = unicode(r.frame.toHtml())

Selenium + Python

Другой способ — использовать Selenium и PhantomJS (так чтобы GUI браузера не появлялся):

import selenium.webdriver as webdriver
import contextlib
import os
import lxml.html as LH

# define path to the phantomjs binary
phantomjs = os.path.expanduser('~/bin/phantomjs')
url = 'http://www.scoreboard.com/game/6LeqhPJd/#game-summary'
with contextlib.closing(webdriver.PhantomJS(phantomjs)) as driver:
    driver.get(url)
    content = driver.page_source
    doc = LH.fromstring(content)   
    result = []
    for tr in doc.xpath('//tr[td[@class="left summary-horizontal"]]'):
        row = []
        for elt in tr.xpath('td'):
            row.append(elt.text_content())
        result.append(u', '.join(row[1:]))
    print(u'\n'.join(result))

Парсинг

import lxml.html as LH

def clean(text):
    return text.replace(u'\xa0', u'')

doc = LH.fromstring(content)   
result = []
for tr in doc.xpath('//tr[td[@class="left summary-horizontal"]]'):
    row = []
    for elt in tr.xpath('td'):
        row.append(clean(elt.text_content()))
    result.append(u', '.join(row[1:]))
print(u'\n'.join(result))

Полезные ссылки

Spread the love
Запись опубликована в рубрике IT рецепты. Добавьте в закладки постоянную ссылку.

Добавить комментарий