Возможно ли Scrapy получить простой текст из необработанных данных HTML?
Например:
scrapy shell http://scrapy.org/
content = hxs.select('//*[@id="content"]').extract()[0]
print content
Затем я получаю следующий необработанный HTML-код:
<div id="content">
<h2>Welcome to Scrapy</h2>
<h3>What is Scrapy?</h3>
<p>Scrapy is a fast high-level screen scraping and web crawling
framework, used to crawl websites and extract structured data from their
pages. It can be used for a wide range of purposes, from data mining to
monitoring and automated testing.</p>
<h3>Features</h3>
<dl>
<dt>Simple</dt>
<dt>
</dt>
<dd>Scrapy was designed with simplicity in mind, by providing the features
you need without getting in your way
</dd>
<dt>Productive</dt>
<dd>Just write the rules to extract the data from web pages and let Scrapy
crawl the entire web site for you
</dd>
<dt>Fast</dt>
<dd>Scrapy is used in production crawlers to completely scrape more than
500 retailer sites daily, all in one server
</dd>
<dt>Extensible</dt>
<dd>Scrapy was designed with extensibility in mind and so it provides
several mechanisms to plug new code without having to touch the framework
core
</dd>
<dt>Portable, open-source, 100% Python</dt>
<dd>Scrapy is completely written in Python and runs on Linux, Windows, Mac and BSD</dd>
<dt>Batteries included</dt>
<dd>Scrapy comes with lots of functionality built in. Check <a
href="#" onclick="location.href='http://doc.scrapy.org/en/latest/intro/overview.html#what-else'; return false;">this
section</a> of the documentation for a list of them.
</dd>
<dt>Well-documented & well-tested</dt>
<dd>Scrapy is <a href="/doc/">extensively documented</a> and has an comprehensive test suite
with <a href="#" onclick="location.href='http://static.scrapy.org/coverage-report/'; return false;">very good code
coverage</a></dd>
<dt><a href="/community">Healthy community</a></dt>
<dd>
1,500 watchers, 350 forks on Github (<a href="#" onclick="location.href='https://github.com/scrapy/scrapy'; return false;">link</a>)<br>
700 followers on Twitter (<a href="#" onclick="location.href='http://twitter.com/ScrapyProject'; return false;">link</a>)<br>
850 questions on Qaru (<a href="#" onclick="location.href='http://stackoverflow.com/tags/scrapy/info'; return false;">link</a>)<br>
200 messages per month on mailing list (<a
href="#" onclick="location.href='https://groups.google.com/forum/?fromgroups#!aboutgroup/scrapy-users'; return false;">link</a>)<br>
40-50 users always connected to IRC channel (<a href="#" onclick="location.href='http://webchat.freenode.net/?channels=scrapy'; return false;">link</a>)
</dd>
<dt><a href="/support">Commercial support</a></dt>
<dd>A few companies provide Scrapy consulting and support</dd>
<p>Still not sure if Scrapy is what you're looking for?. Check out <a
href="#" onclick="location.href='http://doc.scrapy.org/en/latest/intro/overview.html'; return false;">Scrapy at a
glance</a>.
</p>
<h3>Companies using Scrapy</h3>
<p>Scrapy is being used in large production environments, to crawl
thousands of sites daily. Here is a list of <a href="/companies/">Companies
using Scrapy</a>.</p>
<h3>Where to start?</h3>
<p>Start by reading <a href="#" onclick="location.href='http://doc.scrapy.org/en/latest/intro/overview.html'; return false;">Scrapy at a glance</a>,
then <a href="/download/">download Scrapy</a> and follow the <a
href="#" onclick="location.href='http://doc.scrapy.org/en/latest/intro/tutorial.html'; return false;">Tutorial</a>.
</p></dl>
</div>
Но я хочу получить простой текст прямо из скрапа.
Я не хочу использовать селекторы xPath для извлечения тегов p
, h2
, h3
..., поскольку я сканирую веб-сайт, основное содержание которого встроено в table
, tbody
; рекурсивно. Найти xPath может быть утомительным занятием.
Может ли это быть реализовано встроенной функцией в Scrapy? Или мне нужны внешние инструменты для его преобразования? Я прочитал все документы Scrapy, но ничего не получил.
Это пример сайта, который может конвертировать необработанный HTML в простой текст: http://beaker.mailchimp.com/html-to-text
Ответы
Ответ 1
Scrapy не имеет встроенной функции. html2text - это то, что вы ищете.
Здесь образец spider, который сбрасывает страницу pikon wikipedia, получает первый абзац, используя xpath и преобразует html в обычный текст, используя html2text
:
from scrapy.selector import HtmlXPathSelector
from scrapy.spider import BaseSpider
import html2text
class WikiSpider(BaseSpider):
name = "wiki_spider"
allowed_domains = ["www.wikipedia.org"]
start_urls = ["http://en.wikipedia.org/wiki/Python_(programming_language)"]
def parse(self, response):
hxs = HtmlXPathSelector(response)
sample = hxs.select("//div[@id='mw-content-text']/p[1]").extract()[0]
converter = html2text.HTML2Text()
converter.ignore_links = True
print(converter.handle(sample)) #Python 3 print syntax
печатает:
** Python ** - широко используемый язык программирования высокого уровня. [11] [12] [13] В его философии дизайна подчеркивается код читаемость и ее синтаксис позволяют программистам выражать концепции в меньше строк кода, чем это было бы возможно на таких языках, как С. [14] [15] Язык предоставляет конструкции, предназначенные для программ в малых и больших масштабах. [16]
Ответ 2
Другое решение, использующее lxml.html
tostring()
с параметром method="text"
. lxml
используется внутри Scrapy. (параметр encoding=unicode
обычно то, что вы хотите.)
Подробнее см. http://lxml.de/api/lxml.html-module.html.
from scrapy.spider import BaseSpider
import lxml.etree
import lxml.html
class WikiSpider(BaseSpider):
name = "wiki_spider"
allowed_domains = ["www.wikipedia.org"]
start_urls = ["http://en.wikipedia.org/wiki/Python_(programming_language)"]
def parse(self, response):
root = lxml.html.fromstring(response.body)
# optionally remove tags that are not usually rendered in browsers
# javascript, HTML/HEAD, comments, add the tag names you dont want at the end
lxml.etree.strip_elements(root, lxml.etree.Comment, "script", "head")
# complete text
print lxml.html.tostring(root, method="text", encoding=unicode)
# or same as in alecxe example spider,
# pinpoint a part of the document using XPath
#for p in root.xpath("//div[@id='mw-content-text']/p[1]"):
# print lxml.html.tostring(p, method="text")
Ответ 3
В настоящий момент я не думаю, что вам нужно установить какую-либо стороннюю библиотеку. scrapy предоставляет эту функцию с помощью селекторов:
Предположим, что этот сложный селектор:
sel = Selector(text='<a href="#">Click here to go to the <strong>Next Page</strong></a>')
мы можем получить весь текст, используя:
text_content = sel.xpath("//a[1]//text()").extract()
# which results [u'Click here to go to the ', u'Next Page']
тогда вы можете легко объединить их:
' '.join(text_content)
# Click here to go to the Next Page