我使用response.xpath('// *')re_first()提取js數據,稍後將其轉換爲python原生數據。問題是提取/重方法似乎並沒有提供一種方式來不是所享有的HTML,即如何從Scrapy選擇器中提取原始html?
原始的HTML:
{my_fields:['O'Connor Park'], }
提取輸出:
{my_fields:['O'Connor Park'], }
把這個輸出爲JSON韓元沒有工作。
最簡單的方法是什麼?
我使用response.xpath('// *')re_first()提取js數據,稍後將其轉換爲python原生數據。問題是提取/重方法似乎並沒有提供一種方式來不是所享有的HTML,即如何從Scrapy選擇器中提取原始html?
原始的HTML:
{my_fields:['O'Connor Park'], }
提取輸出:
{my_fields:['O'Connor Park'], }
把這個輸出爲JSON韓元沒有工作。
最簡單的方法是什麼?
簡短的回答:
.re()
和.re_first()
方法取代HTML實體(除<
,&
).extract()
或.extract_first()
得到原始的HTML(或原始的JavaScript指令),並使用Python提取的re
模塊提取字符串長答案:
我們來看一個示例輸入和從HTML中提取Javascript數據的各種方法。
樣本HTML:
<html lang="en">
<body>
<div>
<script type="text/javascript">
var i = {a:['O'Connor Park']}
</script>
</div>
</body>
</html>
使用scrapy選擇,這是下面使用parsel庫,你可以提取的JavaScript的幾種方法片段:
>>> import scrapy
>>> t = """<html lang="en">
... <body>
... <div>
... <script type="text/javascript">
... var i = {a:['O'Connor Park']}
... </script>
...
... </div>
... </body>
... </html>
... """
>>> selector = scrapy.Selector(text=t, type="html")
>>>
>>> # extracting the <script> element as raw HTML
>>> selector.xpath('//div/script').extract_first()
u'<script type="text/javascript">\n var i = {a:[\'O'Connor Park\']}\n </script>'
>>>
>>> # only getting the text node inside the <script> element
>>> selector.xpath('//div/script/text()').extract_first()
u"\n var i = {a:['O'Connor Park']}\n "
>>>
現在,使用.re
(或.re_first
)你得到不同的結果:
>>> # I'm using a very simple "catch-all" regex
>>> # you are probably using a regex to extract
>>> # that specific "O'Connor Park" string
>>> selector.xpath('//div/script/text()').re_first('.+')
u" var i = {a:['O'Connor Park']}"
>>>
>>> # .re() on the element itself, one needs to handle newlines
>>> selector.xpath('//div/script').re_first('.+')
u'<script type="text/javascript">' # only first line extracted
>>> import re
>>> selector.xpath('//div/script').re_first(re.compile('.+', re.DOTALL))
u'<script type="text/javascript">\n var i = {a:[\'O\'Connor Park\']}\n </script>'
>>>
HTML實體'
已被替換爲apostrophe。這是由於在.re/re_first
實施w3lib.html.replace_entities()
調用(見parsel
源代碼,extract_regex
功能),這是不使用時簡單地調用extract()
或extract_first()
您還可以利用所使用的Selector
類的相同功能extract
方法,但有不同的參數:
from lxml import etree
etree.tostring(selector._root)
優秀的答案! Scrapy的文檔使這些相關方法的不一致性更加混亂。它不僅沒有提到html實體,而且還提到「百分比編碼的內容沒有被引用」。僅通過extract()。這意味着如果有任何提取是比re()更多的解碼。 – jayshilling