我正在尝试制作一张桌子,在其中我收集this page中每个作曲家的所有作品,并通过添加“得分”来安排它们,例如使用Python脚本,第300名获得1分,第10名获得290分,依此类推。
但是,BeautifulSoup似乎找不到SampleFileName2.file
元素。我究竟做错了什么?页面HTML的屏幕截图:https://gyazo.com/73ff53fb332755300d9b7450011a7130
我已经尝试使用li
,soup.li
和soup.findAll("li")
,但是全部返回“ none”或类似的值。打印soup.find_all("li")
确实会返回正文,所以我认为我有一个HTML文档。
soup.body
我希望这能给我至少一个from bs4 import BeautifulSoup as bsoup
import requests
link = "https://halloffame.classicfm.com/2019/"
response = requests.get(link)
soup = bsoup(response.text, "html.parser")
print(soup.li)
项,但它返回li
。
答案 0 :(得分:0)
我没有看到300-1的所有排名。有时页面仅显示148,其他时候显示146,而我所看到的最低值是143。不知道这是否是设计缺陷/错误。该页面使用javascript更新,这就是为什么您得到一个空列表的原因。该内容尚未呈现。
requests
仅返回不依赖javascript进行渲染的内容,即,您无法获得使用浏览器时看到的所有内容,如果启用了javascript,将允许以各种形式加载其他内容页面上的脚本运行。这是现代响应/动态网页的一项功能,例如,当您在页面上进行选择时,您不再需要更新整个页面。
通常,您可以使用开发工具 F12 来检查网页用于通过网络标签更新内容的网络流量。打开网络标签,刷新整个页面,然后在XHR上进行过滤。
在这种情况下,信息实际上是从已经保存该信息的脚本标签中提取的。您可以打开“元素”标签(Chrome),然后执行 Ctrl + F 并搜索作曲家的名字。您会发现一个匹配发生在脚本标记中。我使用正则表达式通过在javascript var songs = [];
上进行匹配来找到此脚本标签,然后在随后的正则表达式组中包含包含作曲家信息的对象。
目标脚本标记的示例:
您可以从脚本标签中获取这些
import requests
from bs4 import BeautifulSoup as bs
import re
soup = bs(requests.get('https://halloffame.classicfm.com/2019/', 'lxml').content, 'lxml')
r = re.compile(r'var songs = \[\];(.*)' , re.DOTALL)
data = soup.find('script', text=r).text
script = r.findall(data)[0].strip()
rp = re.compile(r'position:\s+(\d+)')
rankings = rp.findall(script)
rt = re.compile(r'title:\s+"(.*)"')
titles = rt.findall(script)
print(len(titles))
print(len(rankings))
如果您可以找到这些排名的其余部分,则可以在颠倒排名列表的同时压缩列表
results = list(zip(titles, rankings[::-1]))
无论哪种方式,您都可以使用标题的len生成一个反向编号列表,以给出排名:
rankings = list(range(len(titles), 0, -1))
results = list(zip(titles, rankings[::-1]))