我想从这个链接link example: 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
访问。
编辑2:我尝试使用这个stackoverflow question中投票最多的答案,但未成功。可能是周围的解决方案。
如果您不打算像@Ali建议的那样通过selenium
尝试浏览器自动化,则必须解析包含所需信息的javascript。你可以用不同的方式做到这一点。这是一个工作代码,通过script
定位regular expression pattern,然后提取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
使用javascript对数据进行数据绑定,如“data-bind”属性所示。
但是,如果您下载包含例如wget
,你会看到在初始加载时,rankingText值实际上在这个脚本元素中:
<script type="text/javascript"
profile: {
...
"ranking": 96,
"rankingText": "96th",
"highestRanking": 3,
"highestRankingText": "3rd",
...
所以你可以改用它。
我在纯文本上使用正则表达式解决了你的问题:
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'等
这可能是因为动态数据填充。
一些javascript代码,在页面加载后填写此标记。因此,如果您使用请求获取html,它尚未填充。
<h4 data-bind="text: rankingText"></h4>
请看看Selenium web driver。使用此驱动程序,您可以正常获取整个页面并运行js。