【问题标题】:How to get data from <script> with var using beautifulsoup?如何使用 beautifulsoup 从 <script> 中获取数据?
【发布时间】:2021-10-31 20:34:41
【问题描述】:

使用arsenic库抓取网页,然后用beautifulsoup解析网页源。 Soup 包含一个带有大量脚本的大型 html。我需要 -9 从最后。

page_source = await session.get_page_source()
    soup = bs(page_source, 'html.parser')
    scripts = soup.find_all('script')
    script9 = scripts[-9].next

这里是脚本9:

    sometext;
var thumbdata = {
  thumbs: [{avatar: "/i/nophoto.jpg", username: "IslandGirlSearching",la:"0 second ",chatid: "0",userid: "2088789", age:"21",city:"Cebu"},{avatar: "/p/2021-08/Cristina266/ava-1629535964.jpg", username: "Cristina266",la:"0 second ",chatid: "0",userid: "2095868", age:"26",city:"Pasig City"}  ] }; 
  var source = sometext;

然后我按照你分享的例子:

    pattern = re.compile(r"var thumbdata = {\n"
                         r"(.*?);")

    m = pattern.match(script9.string)
    thumbs = json.loads(m.groups()[0])

    for thumb in thumbs:
        print(thumb)

检查了我的正则表达式,它是正确的。但是当我执行此代码时,我得到属性错误:

AttributeError: 'NoneType' object has no attribute 'groups'

【问题讨论】:

标签: python json parsing beautifulsoup


【解决方案1】:

您的方法仍有几个问题:

  1. 要将字符串传递给json.loads(),它需要是有效的JSON;否则,你会得到例外。对于您尝试捕获的内容,您需要将领先的 { 令牌作为捕获组的一部分。像这样合并你的两个独立的模式:

    var thumbdata = ({\n.*?);
    

    Regex101

  2. 您会注意到即使 with 更改为获取前导花括号标记,您提取的字符串 仍然 不是有效的 JSON。虽然普通的 JavaScript 对象并非如此,但所有键名都必须用引号括起来;您将提取的文本不会预先执行此操作。因此,您需要将内置的 JSON 解析器(它严格符合规范,并且不会按原样将这些数据解析为 JSON)换成 hjson 之类的东西,它没有实现具有此限制的规范。

    Relevant SO thread

  3. re.match() 的行为不像你想象的那样。深入了解the documentation for this method 在这种特定情况下很有启发性(强调我的):

    请注意,即使在MULTILINE 模式下,re.match() 也只会匹配字符串的开头,而不是每行的开头

    这很重要,因为script9 中的字符串数据以任何根据您的模式被视为“匹配”的数据开头。相反,请将re.match() 的调用替换为re.search()

对上述更改进行更多调整,您的代码将类似于以下内容:

import re
import hjson

script9 = '''    sometext;
var thumbdata = {
  thumbs: [{avatar: "/i/nophoto.jpg", username: "IslandGirlSearching",la:"0 second ",chatid: "0",userid: "2088789", age:"21",city:"Cebu"},{avatar: "/p/2021-08/Cristina266/ava-1629535964.jpg", username: "Cristina266",la:"0 second ",chatid: "0",userid: "2095868", age:"26",city:"Pasig City"}  ] }; 
  var source = sometext;
'''

pattern = re.compile(r"var thumbdata = ({\n.*?);")

m = pattern.search(script9)
thumbs = list(hjson.loads(m.groups()[0]).items())
print(thumbs)

Repl.it

输出:

[('thumbs', [OrderedDict([('avatar', '/i/nophoto.jpg'), ('username', 'IslandGirlSearching'), ('la', '0 second '), ('chatid', '0'), ('userid', '2088789'), ('age', '21'), ('city', 'Cebu')]), OrderedDict([('avatar', '/p/2021-08/Cristina266/ava-1629535964.jpg'), ('username', 'Cristina266'), ('la', '0 second '), ('chatid', '0'), ('userid', '2095868'), ('age', '26'), ('city', 'Pasig City')])])]
('thumbs', [OrderedDict([('avatar', '/i/nophoto.jpg'), ('username', 'IslandGirlSearching'), ('la', '0 second '), ('chatid', '0'), ('userid', '2088789'), ('age', '21'), ('city', 'Cebu')]), OrderedDict([('avatar', '/p/2021-08/Cristina266/ava-1629535964.jpg'), ('username', 'Cristina266'), ('la', '0 second '), ('chatid', '0'), ('userid', '2095868'), ('age', '26'), ('city', 'Pasig City')])])

【讨论】:

  • 谢谢,现在它可以工作了,但我有一个关于thumbs = list(hjson.loads(m.groups()[0]).items()) 的问题,是否可以获得一个包含列表的列表,以便我可以迭代它们并读取里面的光盘?
猜你喜欢
  • 2021-07-07
  • 1970-01-01
  • 2019-05-02
  • 2020-06-06
  • 2023-04-08
  • 2021-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多