用 Scrapy 在 JSON 中抓取 HTML
Scraping HTML inside JSON with Scrapy
我正在请求一个响应为 JSON 的网站:
{
"success": true,
"response": "<html>... html goes here ...</html>"
}
我已经看到了报废 HTML 或 JSON 的两种方法,但还没有找到如何在 JSON 内报废 HTML。是否可以使用 scrapy 来做到这一点?
一种方法是从 JSON 数据中的 HTML 构建一个 scrapy.Selector
。
我假设您有 Response
对象,其中包含 JSON 数据,可通过 response.text
获得。
(下面,我正在构建一个测试响应来玩(我正在使用带有 Python 3 的 scrapy 1.1):
response = scrapy.http.TextResponse(url='http://www.example.com/json', body=r'''
{
"success": true,
"response": "<html>\n <head>\n <base href='http://example.com/' />\n <title>Example website</title>\n </head>\n <body>\n <div id='images'>\n <a href='image1.html'>Name: My image 1 <br /><img src='image1_thumb.jpg' /></a>\n <a href='image2.html'>Name: My image 2 <br /><img src='image2_thumb.jpg' /></a>\n <a href='image3.html'>Name: My image 3 <br /><img src='image3_thumb.jpg' /></a>\n <a href='image4.html'>Name: My image 4 <br /><img src='image4_thumb.jpg' /></a>\n <a href='image5.html'>Name: My image 5 <br /><img src='image5_thumb.jpg' /></a>\n </div>\n </body>\n</html>"
}
''', encoding='utf8')
)
使用 json
模块你可以获得这样的 HTML 数据:
import json
data = json.loads(response.text)
你得到类似的东西:
>>> data
{'success': True, 'response': "<html>\n <head>\n <base href='http://example.com/' />\n <title>Example website</title>\n </head>\n <body>\n <div id='images'>\n <a href='image1.html'>Name: My image 1 <br /><img src='image1_thumb.jpg' /></a>\n <a href='image2.html'>Name: My image 2 <br /><img src='image2_thumb.jpg' /></a>\n <a href='image3.html'>Name: My image 3 <br /><img src='image3_thumb.jpg' /></a>\n <a href='image4.html'>Name: My image 4 <br /><img src='image4_thumb.jpg' /></a>\n <a href='image5.html'>Name: My image 5 <br /><img src='image5_thumb.jpg' /></a>\n </div>\n </body>\n</html>"}
然后你可以像这样构建一个新的选择器:
selector = scrapy.Selector(text=data['response'], type="html")
之后您可以在其上使用 XPath 或 CSS 选择器:
>>> selector.xpath('//title/text()').extract()
['Example website']
你可以尝试 json.loads(initial_response) ,所以你得到一个字典并可以使用他的键,比如 ['response']
好吧,还有另一种方法,您绝对不需要构造响应 object.You 可以使用 lxml 来解析您的 html 文本。你不需要安装任何新的库,因为 Scrapy Selector 是基于 lxml 的。只需将下面的代码添加到 import lxml lib.
from lxml import etree
这是一个例子,假设 json 响应是:
{
"success": true,
"htmlinjson": "<html><body> <p id='p1'>p111111</p> <p id='p2'>p22222</p> </html>"
}
通过以下方式从 json 响应中提取 html 文本:
import json
htmlText = json.loads(response.text)['htmlinjson']
然后构造一个 lxml xpath 选择器使用:
from lxml import etree
resultPage = etree.HTML(htmlText)
现在使用 lxml 选择器提取 id="p1" 节点
的文本,基于 xpath 就像 scrapy xpath 选择器做的那样:
print resultPage.xpath('//p[@id="p1"]')[0].text
您将获得:
p111111
希望对您有所帮助:)
我正在请求一个响应为 JSON 的网站:
{
"success": true,
"response": "<html>... html goes here ...</html>"
}
我已经看到了报废 HTML 或 JSON 的两种方法,但还没有找到如何在 JSON 内报废 HTML。是否可以使用 scrapy 来做到这一点?
一种方法是从 JSON 数据中的 HTML 构建一个 scrapy.Selector
。
我假设您有 Response
对象,其中包含 JSON 数据,可通过 response.text
获得。
(下面,我正在构建一个测试响应来玩(我正在使用带有 Python 3 的 scrapy 1.1):
response = scrapy.http.TextResponse(url='http://www.example.com/json', body=r'''
{
"success": true,
"response": "<html>\n <head>\n <base href='http://example.com/' />\n <title>Example website</title>\n </head>\n <body>\n <div id='images'>\n <a href='image1.html'>Name: My image 1 <br /><img src='image1_thumb.jpg' /></a>\n <a href='image2.html'>Name: My image 2 <br /><img src='image2_thumb.jpg' /></a>\n <a href='image3.html'>Name: My image 3 <br /><img src='image3_thumb.jpg' /></a>\n <a href='image4.html'>Name: My image 4 <br /><img src='image4_thumb.jpg' /></a>\n <a href='image5.html'>Name: My image 5 <br /><img src='image5_thumb.jpg' /></a>\n </div>\n </body>\n</html>"
}
''', encoding='utf8')
)
使用 json
模块你可以获得这样的 HTML 数据:
import json
data = json.loads(response.text)
你得到类似的东西:
>>> data
{'success': True, 'response': "<html>\n <head>\n <base href='http://example.com/' />\n <title>Example website</title>\n </head>\n <body>\n <div id='images'>\n <a href='image1.html'>Name: My image 1 <br /><img src='image1_thumb.jpg' /></a>\n <a href='image2.html'>Name: My image 2 <br /><img src='image2_thumb.jpg' /></a>\n <a href='image3.html'>Name: My image 3 <br /><img src='image3_thumb.jpg' /></a>\n <a href='image4.html'>Name: My image 4 <br /><img src='image4_thumb.jpg' /></a>\n <a href='image5.html'>Name: My image 5 <br /><img src='image5_thumb.jpg' /></a>\n </div>\n </body>\n</html>"}
然后你可以像这样构建一个新的选择器:
selector = scrapy.Selector(text=data['response'], type="html")
之后您可以在其上使用 XPath 或 CSS 选择器:
>>> selector.xpath('//title/text()').extract()
['Example website']
你可以尝试 json.loads(initial_response) ,所以你得到一个字典并可以使用他的键,比如 ['response']
好吧,还有另一种方法,您绝对不需要构造响应 object.You 可以使用 lxml 来解析您的 html 文本。你不需要安装任何新的库,因为 Scrapy Selector 是基于 lxml 的。只需将下面的代码添加到 import lxml lib.
from lxml import etree
这是一个例子,假设 json 响应是:
{
"success": true,
"htmlinjson": "<html><body> <p id='p1'>p111111</p> <p id='p2'>p22222</p> </html>"
}
通过以下方式从 json 响应中提取 html 文本:
import json
htmlText = json.loads(response.text)['htmlinjson']
然后构造一个 lxml xpath 选择器使用:
from lxml import etree
resultPage = etree.HTML(htmlText)
现在使用 lxml 选择器提取 id="p1" 节点
的文本,基于 xpath 就像 scrapy xpath 选择器做的那样:
print resultPage.xpath('//p[@id="p1"]')[0].text
您将获得:
p111111
希望对您有所帮助:)