我一整天都在谷歌搜索,没有找到答案,所以如果已经回答,请提前道歉。
我正试图从大量不同的网站获取所有可见文本。原因是我想处理文本以最终对网站进行分类。
经过几天的研究,我认为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和Beautiful Soup的原因是因为我想要JavaScript招标文本
答案 0 :(得分:9)
使用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和刷新完成)。
答案 1 :(得分:5)
以下是@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
我把你的任务分成两部分:
代码仅通过缓存连接。您可以在一个进程中获取页面并在另一个进程中提取文本,或者稍后使用不同的算法推迟执行。