美丽的汤解析网页
Posted
技术标签:
【中文标题】美丽的汤解析网页【英文标题】:Beautiful soup parsing web page 【发布时间】:2020-03-05 17:36:53 【问题描述】:我正在尝试使用 BS 抓取以下网页:https://www.racingpost.com
。
例如,我想提取所有课程名称。课程名称在此标签下:
<span class="rh-cardsMatrix__courseName">Wincanton</span>
我的代码在这里:
from bs4 import BeautifulSoup
import requests
import pandas as pd
url = "https://www.racingpost.com"
response = requests.get(url)
data = response.text
soup = BeautifulSoup(data, "html.parser")
pages = soup.find_all('span','class':'rh-cardsMatrix__courseName')
for page in pages:
print(page.text)
而且我没有得到任何输出。我认为它在解析方面存在一些问题,并且我已经尝试了所有可用的 BS 解析器。有人可以在这里建议吗?甚至可能与BS有关吗?
【问题讨论】:
soup.find_all('span')
是否返回所有span
元素?如果是这样,您的过滤器需要工作。如果你愿意,你可以传递一个函数作为过滤器。
soup.find_all('span') 返回一些跨度元素,但它们不是我从“检查元素”选项中看到的
如果您的问题得到解决,请将答案标记为已接受,以便其他人可以看到您的问题已得到解答。
【参考方案1】:
您要查找的数据似乎隐藏在原始 HTML 末尾的脚本块中。
你可以试试这样的:
import requests
from bs4 import BeautifulSoup
import json
import pandas as pd
from pandas import json_normalize
url = 'https://www.racingpost.com'
res = requests.get(url).text
raw = res.split('cardsMatrix":"courses":')[1].split(',"date":"2020-03-06","heading":"Tomorrow\'s races"')[0]
data = json.loads(raw)
df = json_normalize(data)
输出:
id abandoned allWeather surfaceType colour name countryCode meetingUrl hashName meetingTypeCode races
0 1083 False True Polytrack 3 Chelmsford GB /racecards/1083/chelmsford-aw/2020-03-06 chelmsford-aw Flat ['id': 753047, 'abandoned': False, 'result': ...
1 1212 False False 4 Ffos Las GB /racecards/1212/ffos-las/2020-03-06 ffos-las Jumps ['id': 750498, 'abandoned': False, 'result': ...
2 1138 False True Polytrack 11 Dundalk IRE /racecards/1138/dundalk-aw/2020-03-06 dundalk-aw Flat ['id': 753023, 'abandoned': False, 'result': ...
3 513 False True Tapeta 5 Wolverhampton GB /racecards/513/wolverhampton-aw/2020-03-06 wolverhampton-aw Flat ['id': 750658, 'abandoned': False, 'result': ...
4 565 False False 0 Jebel Ali UAE /racecards/565/jebel-ali/2020-03-06 jebel-ali Flat ['id': 753155, 'abandoned': False, 'result': ...
5 206 False False 0 Deauville FR /racecards/206/deauville/2020-03-06 deauville Flat ['id': 753186, 'abandoned': False, 'result': ...
6 54 True False 1 Sandown GB /racecards/54/sandown/2020-03-06 sandown Jumps ['id': 750510, 'abandoned': True, 'result': F...
7 30 True False 2 Leicester GB /racecards/30/leicester/2020-03-06 leicester Jumps ['id': 750501, 'abandoned': True, 'result': F...
警告:请注意,您必须手动搜索字符串以在末尾正确拆分 res
。
编辑:更强大的解决方案。
要获取整个脚本块并从那里解析,请尝试以下代码:
url = 'https://www.racingpost.com'
res = requests.get(url).content
soup = BeautifulSoup(res)
# salient data seems to be in 20th script block
data = soup.find_all("script")[19].text
clean = data.split('window.__PRELOADED_STATE = ')[1].split(";\n")[0]
clean = json.loads(clean)
clean.keys()
输出:
['stories', 'bookmakers', 'panelTemplate', 'cardsMatrix', 'advertisement']
然后检索例如数据保存到密钥cardsMatrix
:
parsed = json_normalize(clean["cardsMatrix"]).courses.values[0]
pd.DataFrame(parsed)
再次输出上述内容(但具有更强大的解决方案):
id abandoned allWeather surfaceType colour name countryCode meetingUrl hashName meetingTypeCode races
0 1083 False True Polytrack 3 Chelmsford GB /racecards/1083/chelmsford-aw/2020-03-06 chelmsford-aw Flat ['id': 753047, 'abandoned': False, 'result': ...
1 1212 False False 4 Ffos Las GB /racecards/1212/ffos-las/2020-03-06 ffos-las Jumps ['id': 750498, 'abandoned': False, 'result': ...
【讨论】:
【参考方案2】:查看https://www.racingpost.com
的源码,没有元素类名rh-cardsMatrix__courseName
。在页面上查询它表明它在页面呈现时确实存在。这表明具有该类名的元素是使用 javascript 生成的,而 BeautifulSoup 不支持(它不运行 JavaScript)。
您将希望在网页上找到返回创建这些元素的数据的端点(例如,查找 XHR 以获取数据)并使用这些端点来获取您需要的数据。
【讨论】:
【参考方案3】:感谢 mattbasta 的回答,它引导我解决了这个问题,解决了我的问题: 汤= BeautifulSoup(数据,“html.parser”) pages = soup.find_all('span','class':'rh-cardsMatrix__courseName')
PyQt4 to PyQt5 -> mainFrame() deprecated, need fix to load web pages
【讨论】:
以上是关于美丽的汤解析网页的主要内容,如果未能解决你的问题,请参考以下文章