Skip to content Skip to sidebar Skip to footer

Python:getting Text From Html Using Beautifulsoup

I am trying to extract the ranking text number from this link link example: kaggle user ranking no1. More clear in an image: I am using the following code: def get_single_item_dat

Solution 1:

If you aren't going to try browser automation through selenium as @Ali suggested, you would have to parse the javascript containing the desired information. You can do this in different ways. Here is a working code that locates the script by a regular expression pattern, then extracts the profile object, loads it with json into a Python dictionary and prints out the desired ranking:

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"]

Prints:

1 1st

Solution 2:

The data is databound using javascript, as the "data-bind" attribute suggests.

However, if you download the page with e.g. wget, you'll see that the rankingText value is actually there inside this script element on initial load:

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

So you could use that instead.

Solution 3:

I have solved your problem using regex on the plain text:

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)

This return only the rank number, but I think it will help you, since from what I see the rankText just add 'st', 'th' and etc to the right of the number

Solution 4:

This could because of dynamic data filling.

Some javascript code, fill this tag after page loading. Thus if you fetch the html using requests it is not filled yet.

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

Please take a look at Selenium web driver. Using this driver you can fetch the complete page and running js as normal.

Post a Comment for "Python:getting Text From Html Using Beautifulsoup"