我正在请求一个网站,其响应是这样的JSON:
{
"success": true,
"response": "<html>... html goes here ...</html>"
}
我已经看到了废弃HTML或JSON的两种方法,但还没有找到如何在JSON中废弃HTML。是否可以使用scrapy来做到这一点?
答案 0 :(得分:7)
一种方法是在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']
答案 1 :(得分:0)
你可以尝试json.loads(initial_response),这样你就可以使用他的密钥,比如['response']
答案 2 :(得分:0)
好吧,还有另外一种方法,你绝对不需要构建一个响应对象。你可以使用lxml来解析你的html文本。您不需要安装任何新的lib,因为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 selcectorfrom lxml import etree
resultPage = etree.HTML(htmlText)
现在使用lxml选择器以id =“p1”提取节点
的文本,基于xpath,就像scrapy xpath选择器一样:
print resultPage.xpath('//p[@id="p1"]')[0].text
你会得到:
p111111
希望有所帮助:)