使用Selenium从网页获取所有可见文本

2024-03-29 13:11:54 发布

您现在位置:Python中文网/ 问答频道 /正文

我已经搜索了一整天都没有找到答案,所以如果已经找到答案,请提前道歉。

我正在尝试从大量不同的网站获取所有可见的文本。原因是我想处理文本,以便最终对网站进行分类。

经过几天的研究,我决定硒是我最好的机会。我找到了一种方法来抓取所有的文本,使用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()

for循环中的if条件试图消除多次获取同一文本的问题-但是,它并没有按计划在某些网页上工作。(这也让脚本慢了很多)

我猜我的问题的原因是-当要求一个元素的内部文本时-我也得到了嵌套在这个元素中的元素的内部文本。

有办法解决这个问题吗?是否有某种主元素我抓取的内部文本?或者一种完全不同的方式来实现我的目标?任何帮助都将非常感谢,因为我对这一个想法。

编辑:我之所以使用Selenium而不是机械化和美观的Soup,是因为我想要JavaScript文本


Tags: 答案text文本import元素for网站driver
2条回答

使用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和refresh完成)。

以下是@unutbu's answer的变体:

#!/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生成的元素)
  • 提取文本

代码只通过缓存连接。您可以在一个进程中获取页面并在另一个进程中提取文本,或者使用不同的算法延迟以后执行。

相关问题 更多 >