4

我正在尝试从此链接链接示例中提取排名文本编号:kaggle userranking no1。图像更清晰:

在此处输入图像描述

我正在使用以下代码:

def get_single_item_data(item_url):
    sourceCode = requests.get(item_url)
    plainText = sourceCode.text
    soup = BeautifulSoup(plainText)
    for item_name in soup.findAll('h4',{'data-bind':"text: rankingText"}):
        print(item_name.string)

item_url = 'https://www.kaggle.com/titericz'   
get_single_item_data(item_url)

结果是None。问题是soup.findAll('h4',{'data-bind':"text: rankingText"})输出:

[<h4 data-bind="text: rankingText"></h4>]

但是在检查时在链接的 html 中是这样的:

<h4 data-bind="text: rankingText">1st</h4>. 可以在图片中看到:

在此处输入图像描述

很明显,缺少文本。我怎样才能超越它?

编辑:在终端打印soup变量我可以看到这个值存在: 在此处输入图像描述

所以应该有办法通过soup.

编辑 2:我尝试使用此stackoverflow question中投票最多的答案,但未成功。可能是那里的解决方案。

4

4 回答 4

4

如果您不打算按照@Ali 的建议尝试浏览器自动化selenium,则必须解析包含所需信息的 javascript。你可以用不同的方式做到这一点。这是一个工作代码,它script通过正则表达式模式定位,然后提取profile对象,将其加载json到 Python 字典中并打印出所需的排名:

import re
import json

from bs4 import BeautifulSoup
import requests


response = requests.get("https://www.kaggle.com/titericz")
soup = BeautifulSoup(response.content, "html.parser")

pattern = re.compile(r"profile: ({.*}),", re.MULTILINE | re.DOTALL)
script = soup.find("script", text=pattern)

profile_text = pattern.search(script.text).group(1)
profile = json.loads(profile_text)

print profile["ranking"], profile["rankingText"]

印刷:

1 1st
于 2015-12-17T15:28:14.990 回答
3

正如“data-bind”属性所暗示的那样,数据是使用 javascript 进行数据绑定的。

但是,如果您使用 eg 下载页面wget,您会看到在初始加载时,rankingText 值实际上存在于此脚本元素中:

<script type="text/javascript"
profile: {
...
   "ranking": 96,
   "rankingText": "96th",
   "highestRanking": 3,
   "highestRankingText": "3rd",
...

所以你可以改用它。

于 2015-12-17T13:56:35.563 回答
0

我已经在纯文本上使用正则表达式解决了您的问题:

def get_single_item_data(item_url):
    sourceCode = requests.get(item_url)
    plainText = sourceCode.text
    #soup = BeautifulSoup(plainText, "html.parser")
    pattern = re.compile("ranking\": [0-9]+")
    name = pattern.search(plainText)
    ranking = name.group().split()[1]
    print(ranking)

item_url = 'https://www.kaggle.com/titericz'
get_single_item_data(item_url)

这仅返回排名编号,但我认为它会对您有所帮助,因为从我看到的 rankText 只需在数字右侧添加“st”、“th”等

于 2015-12-17T18:37:06.823 回答
-1

这可能是因为动态数据填充。

一些javascript代码,页面加载后填写此标签。因此,如果您使用请求获取 html,则它尚未填充。

<h4 data-bind="text: rankingText"></h4>

请查看Selenium 网络驱动程序。使用此驱动程序,您可以获取完整页面并正常运行 js。

于 2015-12-17T13:47:15.580 回答