【问题标题】:How to parse returned Javascript code from get request in Python如何从 Python 中的 get 请求中解析返回的 Javascript 代码
【发布时间】:2019-11-17 00:28:31
【问题描述】:

我正在发送以下获取请求

<a href="#" onclick="new Ajax.Request('/book/reviews/4981?authenticity_token=vxZvklgqILI3SBwtJLDN5DicJKt93LiOWxYwFa%2BrWDdsJxTTAs46WvPN3L1PKNW3qpmacr%2BnWYXexhR%2BfoB3Cw%3D%3D&amp;amp;hide_last_page=true&amp;amp;language_code=en&amp;amp;page=4', {asynchronous:true, evalScripts:true, method:'get', parameters:'authenticity_token=' + encodeURIComponent('FUvf1v6N9TgtBKVmo5I3YLm3yVwb//WU9zZDdj1oWd3GeqSXpGnv0OmBZfbICi8zK7J3hdmEFJ9y5mcd7EN24Q==')}); return false;">4</a>

在 Python 中,我写成

import urllib

URL = 'https://www.goodreads.com/book/reviews/4981?authenticity_token=vxZvklgqILI3SBwtJLDN5DicJKt93LiOWxYwFa%2BrWDdsJxTTAs46WvPN3L1PKNW3qpmacr%2BnWYXexhR%2BfoB3Cw%3D%3D&amp;amp;hide_last_page=true&amp;amp;language_code=en&amp;amp;page=4'

s = 'FUvf1v6N9TgtBKVmo5I3YLm3yVwb//WU9zZDdj1oWd3GeqSXpGnv0OmBZfbICi8zK7J3hdmEFJ9y5mcd7EN24Q=='

PARAMS = {'asynchronous':True, 
 'evalScripts':True, 
 'method':'get', 
 'parameters':'authenticity_token=' + urllib.parse.quote(s.encode("utf-8"))
}

r = requests.get(url = URL, params = PARAMS) 

我对此很陌生,但它似乎被编码成不是 ASCII 外观的文本。返回的代码还包含 HTML 代码,这正是我想要的。 这是返回的一部分:

b'Element.update("reviews", "\\n\\u003cdiv class=\\"bookReviewsPaginationCount\\"\\u003e\\n    
\\u003cspan class=\\"smallText\\"\\u003e\\nShowing 91-120\\n\\u003c/span\\u003e\\n\\n\\u003c/div\\u003e\\n\\n\\n\\u003cdiv id=\\"reviewControls\\"\\n     class=\\"reviewControls u-defaultType clearFix\\"\\u003e\\n   \\u003cdiv class=\\"reviewControls--left\\"\\u003e\\n    
\\u003cspan class=\\"stars staticStars notranslate\\"\\u003e\\u003cspan size=\\"12x12\\" class=\\"staticStar p10\\"\\u003e\\u003c/span\\u003e\\u003cspan size=\\"12x12\\" class=\\"staticStar p10\\"\\u003e\\u003c/span\\u003e\\u003cspan size=\\"12x12\\" class=\\"staticStar p10\\"\\u003e\\u003c/span\\u003e\\u003cspan size=\\"12x12\\" class=\\"staticStar p10\\"\\u003e\\u003c/span\\u003e\\u003cspan size=\\"12x12\\" class=\\"staticStar p3\\"\\u003e\\u003c/span\\u003e\\u003c/span\\u003e\\n    
\\u003cspan class=\\"u-visuallyHidden\\"\\u003eAverage rating\\u003c/span\\u003e\\n    4.07\\n    \\u003cspan class=\\"greyText\\"\\u003e\\u0026nbsp;\\u0026middot;\\u0026nbsp;\\u003c/span\\u003e\\n  \\u003c/div\\u003e\\n  \\u003cdiv class=\\"reviewControls__ratingDetails reviewControls--left rating_graph\\"\\u003e\\n    \\u003cspan id=\\"reviewControls__ratingDetailsMiniGraph\\"\\u003e\\n    \\u003cscript type=\\"text/javascript\\"\\u003e\\n    
//\\u003c![CDATA[\\n      $j(document).ready(function() {\\n        var vis = renderRatingGraph(\\n            [436969, 351497, 175037, 52003, 27985],\\n            \\"reviewControls__ratingDetailsMiniGraph\\");\\n        $j(\\"#reviewControls__ratingDetailsMiniGraph\\").prependTo(\\"#rating_details_tip\\");\\n      });\\n  

有没有办法解析代码?我试过了:

BeautifulSoup scrape from javascript (encoded) variable

但它不适用于我返回的代码。

谢谢

【问题讨论】:

  • 发布您的代码!以便我们发现问题出在哪里!
  • 这是一个bytes 对象,因此请尝试在其上调用.decode()。如果你 print 它而不是查看 REPL 中的转义值,它看起来也会更正常。
  • 好的,我已经添加了更多代码。而@kaya3,.decode() 方法只删除了文本前面的'b'。我还想删除转义字符,如 \u003、\u0026 等
  • 此转义字符仅作为转义字符打印,因为您正在查看它的 repr - 在字符串中它们是被转义的实际字符。尝试在结果上调用print
  • 当我运行print(r.content.decode()) 时,字符串看起来像:Element.update("reviews", "\n\u003cdiv class=\"bookReviewsPaginationCount\"\u003e\n \u003cspan class=\"smallText\"\u003e\nShowing 91-120\n\u003c/span\u003e\n\n\u003c/div\u003e\n\n\n\u003cdiv id=\"reviewControls\"\n class=\"reviewControls u-defaultType clearFix\"\u003e\n \u003cdiv class=\"reviewControls--left\"\u003e\n \u003cspan class=\"stars staticStars notranslate\"\u003e\u003cspan size=\"12x12\" 有没有办法把它变成更易读的代码?

标签: python beautifulsoup


【解决方案1】:

返回的字符串看起来像用于使用字符串文字生成 HTML 元素的 jQuery 代码。您可能需要使用切片r.text[27:-2] 获取该字符串文字,然后使用encode().decode('unicode_escape') 获取可由BeatifulSoup 解析的字符串。

import urllib
import urllib.parse
import requests
from bs4 import BeautifulSoup as Soup

URL = 'https://www.goodreads.com/book/reviews/4981?authenticity_token=vxZvklgqILI3SBwtJLDN5DicJKt93LiOWxYwFa%2BrWDdsJxTTAs46WvPN3L1PKNW3qpmacr%2BnWYXexhR%2BfoB3Cw%3D%3D&amp;amp;hide_last_page=true&amp;amp;language_code=en&amp;amp;page=4'

s = 'FUvf1v6N9TgtBKVmo5I3YLm3yVwb//WU9zZDdj1oWd3GeqSXpGnv0OmBZfbICi8zK7J3hdmEFJ9y5mcd7EN24Q=='

PARAMS = {'asynchronous':True, 
 'evalScripts':True, 
 'method':'get', 
 'parameters':'authenticity_token=' + urllib.parse.quote(s.encode("utf-8"))
}

r = requests.get(url = URL, params = PARAMS) 
soup = Soup(r.text.encode('utf-8'), 'html.parser')

html_str = r.text[27:-2].encode().decode('unicode_escape')
soup = Soup(html_str, "html.parser")
print(soup)

【讨论】:

  • 谢谢,这正是我需要的
猜你喜欢
  • 2021-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-22
  • 1970-01-01
  • 1970-01-01
  • 2018-11-26
相关资源
最近更新 更多