Получение всего видимого текста с веб-страницы с помощью Selenium - PullRequest
11 голосов
/ 31 октября 2011

Я весь день гуглял, не найдя ответа, поэтому заранее извиняюсь, если на этот вопрос уже есть ответ.

Я пытаюсь получить весь видимый текст с большого количества разных сайтов.Причина в том, что я хочу обработать текст, чтобы в итоге классифицировать сайты.

После нескольких дней исследований я решил, что Selenium - мой лучший шанс.Я нашел способ получить весь текст с помощью Selenium, к сожалению, один и тот же текст захватывается несколько раз:

from selenium import webdriver
import codecs

filen = codecs.open('outoput.txt', encoding='utf-8', mode='w+')

driver = webdriver.Firefox()

driver.get("http://www.examplepage.com")

allelements = driver.find_elements_by_xpath("//*")

ferdigtxt = []

for i in allelements:

      if i.text in ferdigtxt:
          pass
  else:
         ferdigtxt.append(i.text)
         filen.writelines(i.text)

filen.close()

driver.quit()

Условие if внутри цикла for является попыткой устраненияпроблема извлечения одного и того же текста несколько раз - однако он работает не так, как запланировано, на некоторых веб-страницах.(это также делает скрипт НАМНОГО более медленным)

Я предполагаю, что причина моей проблемы в том, что - при запросе внутреннего текста элемента - я также получаю внутренний текст элементов, вложенных вэлемент в вопросе.

Есть ли способ обойти это?Есть ли какой-то главный элемент, который я беру с собой во внутреннем тексте?Или совершенно другим способом, который позволил бы мне достичь своей цели?Любая помощь будет принята с благодарностью, поскольку у меня нет идей для этого.

Редактировать: причина, по которой я использовал Selenium, а не Mechanize and Beautiful Soup, в том, что я хотел, чтобы JavaScript предлагал текст

Ответы [ 2 ]

9 голосов
/ 31 октября 2011

Используя lxml , вы можете попробовать что-то вроде этого:

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

url="http://www.yahoo.com"
ignore_tags=('script','noscript','style')
with contextlib.closing(webdriver.Firefox()) as browser:
    browser.get(url) # Load page
    content=browser.page_source
    cleaner=clean.Cleaner()
    content=cleaner.clean_html(content)    
    with open('/tmp/source.html','w') as f:
       f.write(content.encode('utf-8'))
    doc=LH.fromstring(content)
    with open('/tmp/result.txt','w') as f:
        for elt in doc.iterdescendants():
            if elt.tag in ignore_tags: continue
            text=elt.text or ''
            tail=elt.tail or ''
            words=' '.join((text,tail)).strip()
            if words:
                words=words.encode('utf-8')
                f.write(words+'\n') 

Похоже, что это почти весь текст на www.yahoo.com, за исключением текста на изображениях и некоторого текста, который изменяется со временем (возможно, с использованием javascript и обновлением).

5 голосов
/ 31 октября 2011

Вот вариант ответа @ unutbu :

#!/usr/bin/env python
import sys
from contextlib import closing

import lxml.html as html # pip install 'lxml>=2.3.1'
from lxml.html.clean        import Cleaner
from selenium.webdriver     import Firefox         # pip install selenium
from werkzeug.contrib.cache import FileSystemCache # pip install werkzeug

cache = FileSystemCache('.cachedir', threshold=100000)

url = sys.argv[1] if len(sys.argv) > 1 else "https://stackoverflow.com/q/7947579"


# get page
page_source = cache.get(url)
if page_source is None:
    # use firefox to get page with javascript generated content
    with closing(Firefox()) as browser:
        browser.get(url)
        page_source = browser.page_source
    cache.set(url, page_source, timeout=60*60*24*7) # week in seconds


# extract text
root = html.document_fromstring(page_source)
# remove flash, images, <script>,<style>, etc
Cleaner(kill_tags=['noscript'], style=True)(root) # lxml >= 2.3.1
print root.text_content() # extract text

Я разделил вашу задачу на две части:

  • получить страницу (включая созданные элементыпо javascript)
  • извлечь текст

Код подключен только через кеш.Вы можете извлекать страницы в одном процессе и извлекать текст в другом процессе или отложить сделать это позже, используя другой алгоритм.

...