4

このリンク リンクの例からランキング テキスト番号を抽出しようとしています: kaggle user ranking 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: このスタックオーバーフローの質問から最も投票された回答を使用しようとしましたが失敗しました。そのあたりの解決策かもしれません。

4

4 に答える 4

4

selenium@Ali が提案したようにブラウザーの自動化を試行しない場合は、目的の情報を含む JavaScript を解析する必要があります。これはさまざまな方法で行うことができます。以下は、正規表現パターンscriptによってを見つけ、オブジェクトを抽出し、それを Python 辞書にロードして、目的のランキングを出力する作業コードです。profilejson

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)

これはランク番号のみを返しますが、ランクテキストは番号の右側に「st」、「th」などを追加するだけなので、役立つと思います

于 2015-12-17T18:37:06.823 に答える
-1

これは、動的データ入力が原因である可能性があります。

一部の JavaScript コードは、ページの読み込み後にこのタグに入力します。したがって、リクエストを使用して html を取得しても、まだ入力されていません。

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

Selenium web driverをご覧ください。このドライバーを使用すると、完全なページをフェッチし、通常どおり js を実行できます。

于 2015-12-17T13:47:15.580 に答える