尝试在Python中使用Selenium创建循环
我有一个代码可以在这个站点中搜索-->只搜索我想要的有难度的地图,但我不能正确地进行循环尝试在Python中使用Selenium创建循环,python,selenium,selenium-webdriver,Python,Selenium,Selenium Webdriver,我有一个代码可以在这个站点中搜索-->只搜索我想要的有难度的地图,但我不能正确地进行循环 from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from se
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
from time import sleep
# Set link and path
driver = webdriver.Chrome(executable_path=r"C:\Users\Gabri\anaconda3\chromedriver.exe")
driver.get("https://osu.ppy.sh/beatmapsets?m=0")
wait = WebDriverWait(driver, 20)
# Variables, lists and accountants
lista = {}
links, difficulty, maps2, final = [], [], [], []
line, column, = 1, 1
link_test = ''
n = int(input('insert how many maps do you want: '))
c = 1
# Open link in Chrome and search map by map
while True:
if c > n:
break
sleep(1)
wait.until(EC.element_to_be_clickable(
(By.CSS_SELECTOR, f".beatmapsets__items-row:nth-of-type(1)>.beatmapsets__item:nth-of-type(1)")))
games = driver.find_element_by_css_selector(
f".beatmapsets__items-row:nth-of-type({line}) .beatmapsets__item:nth-of-type({column}) .beatmapset-panel__info-row--extra")
actions = ActionChains(driver)
actions.move_to_element(games).perform()
wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, ".beatmaps-popup__group")))
scores = driver.find_elements_by_css_selector(
".beatmaps-popup__group .beatmaps-popup-item__col.beatmaps-popup-item__col--difficulty")
# This part i can't makes automatic, for example, if i wanted to show 6 maps i would have to add 2 more if's
# Changing the variable (line) and (column) accordingly
# I liked to have a loop with 'while' or 'for ... in' but i don't know how make it
# I tried to do a question before start the code like 'how many maps do you want?' and this number would be the times that code would execute
# But no work it =(
if c % 2 != 0:
column = 2
if c % 2 == 0:
line += 1
else:
line += 1
column = 1
# Convert string to float (difficulty numbers)
for score in scores:
a = score.text
b = a.replace(',', '.')
difficulty.append(float(b))
# Save in list 'links' each link corresponding of map that is printing
games.click()
sleep(3)
link_test = driver.current_url
links.append(link_test)
link_test = ''
driver.back()
# Dict with map, link and difficulty
lista = {
'map': f"{c}",
'link': f"{links}",
'difficulty': f"{difficulty}"}
c += 1
# Print each map in dict 'lista'
print(f"Map: {lista['map']}\nLink: {links}\nDifficulty: {lista['difficulty']}\n")
# This part is my filter, if map have difficulty 6.00 or more, it's add to list 'final' for download
for b in difficulty:
if b >= 6.00:
# This slice, the link had printing error 'TypeError: unhashable type: 'list'', i found this way to solve it
# I know that is not the best way to solve this error, but at least i tried =,)
xam = str(links[0])
xam1 = xam.replace("'", '')
xam2 = xam1.replace("[", '')
xam3 = xam2.replace("]", '')
final.append(xam3)
# Clean all lists for no have duplicate items in dict 'lista' when next map is selected
difficulty.clear()
lista.clear()
links.clear()
# Print how many maps with difficulty 6.00 has been found
print(f'There are {len(sorted(set(final)))} maps to download')
# This question is for future download, im still coding this part, so u can ignore this =3
pergunta = input('Do you want to download them? \n[ Y ]\n[ N ]\n>>> ').lower().strip()
# Clean duplicate links and show all links already filtered
if pergunta == 'y':
for x in final:
maps2.append(x)
print(sorted(set(maps2)))
在“如果”部分,我需要帮助使它自动化,以一种对许多“如果”没有用处的方式,就像我做的那样。变量本身加上“v+=n”可能?Idk;-
PS如果您发现任何逻辑错误或某种优化我的代码的方法,我将很乐意学习并修复它
你做的工作比你必须做的多得多。当您在浏览器中访问页面并记录网络流量时,每次向下滚动以加载更多beatmaps时,您都会看到向REST API发出一些XHR(XmlHttpRequest)HTTP GET请求,该请求的响应是JSON,包含您可能需要的所有beatmap信息。您只需模拟HTTP GET请求—无需Selenium:
def get_beatmaps():
import requests
url = "https://osu.ppy.sh/beatmapsets/search"
params = {
"m": "0",
"cursor[approved_date]": "0",
"cursor[_id]": "0"
}
while True:
response = requests.get(url)
response.raise_for_status()
data = response.json()
cursor_id = data["cursor"]["_id"]
if cursor_id == params["cursor[_id]"]:
break
yield from data["beatmapsets"]
params["cursor[approved_date]"] = data["cursor"]["approved_date"]
params["cursor[_id]"] = cursor_id
def main():
from itertools import islice
num_beatmaps = 10 # Get info for first ten beatmaps
beatmaps = list(islice(get_beatmaps(), num_beatmaps))
for beatmap in beatmaps:
print("{} - {}".format(beatmap["artist"], beatmap["title"]))
for version in beatmap["beatmaps"]:
print(" [{}]: {}".format(version["version"], version["difficulty_rating"]))
print()
return 0
if __name__ == "__main__":
import sys
sys.exit(main())
输出:
Aitsuki Nakuru-单色蝴蝶
[吉布恩疯了]:4.55
[兴奋]:5.89
[协作额外]:5.5
[硬]:3.54
[正常]:2.38
甜蜜之旅-巧克力之旅
[结束这一切混乱]:4.15
[口语和塞拉费姆的硬]:3.12
麻生太郎-更多的情人!!
[SS!]:5.75
[索尼克的专家]:5.56
[milr_'s Hard]:3.56
[Dailycare疯了]:4.82
Takayan-金瑞Mina Menhera
[情感]:4.43
[正常]:2.22
[叙述很难]:3.28
朝日-抓住每一天(电视大小)
[美景]:3.7
[康丹]:1.44
[Seren's Oni]:3.16
[XK的Futsuu]:2.01
[ILOVEMARISA's Muzukashii]:2.71
[Xavy抓住时机]:4.06
Swimy-Acchi Muite(电视尺寸)
[往那边看]:4.91
[阿祖杯]:1.72
[拼盘]:2.88
[沙拉]:2.16
[西娅的雨]:4.03
中泽美能里(简历:花泽假名)-美能里no Zokkon Mirai Yohou(电视尺寸)
[专家]:5.49
[正常]:2.34
[苏欧很难]:3.23
【苏欧疯了】:4.38
[另]:4.56
金-儿童唱片(Re:boot)
[硬协作]:3.89
[Maki's Normal]:2.6
[超级细胞和Seto的疯狂]:5.01
[卡格鲁]:6.16
煤球嗜线虫(电视大小)
[只有我才能进入的隐藏地牢]:3.85
[沉默很难]:3
[正常]:2.29
死亡幻想曲
[疯子]:6.06
>>>
现在编写这个示例的方式是,它从API中获取前十个beatmaps,打印艺术家和标题,以及每个版本beatmap的名称和难度。您可以更改它以满足您的需要,并根据难度过滤输出
话虽如此,我对OSU或beatmaps一无所知。如果您能描述最终输出的实际外观,我可以定制我的解决方案。在进行大量测试之前,我解决了所有问题(现在呵呵)。 加上
我非常感谢所有帮助我的人=))我已经看到这篇帖子至少3次了,在过去的2次尝试中,什么对你不起作用?@cruisepandey在最近的2次尝试中,我没有试图对这部分一无所获,因为我把注意力集中在解决其他问题上。我以前一直在等待有人帮助我,但是今天我试图解决这个问题,在这一刻我尝试用+=,做一个简单的自我会计变量,如果我向前一步,我会编辑代码来解释我所做的事情,
行
和列
随着映射数量
数量的增加有什么模式吗?它似乎是从代码片段中随机产生的above@JD2775是的,就像坐标一样,第1行第1列是1°地图,第1行第2列是2°地图,第2行第1列是3°地图。。。我遵循页面的布局,有两列和几行lines@JD2775看到这个例子-->哇,我尝试了一些完全不同的东西,但是我非常喜欢你的代码,哈哈。在最后的代码中(当我解决所有问题时),我将使用列表“maps2”中的链接进行下载,仅使用6.00或更高难度的地图。我需要一段像你一样的代码,但我这样做是因为我尽可能地清理代码,使其更易于阅读;)。我不认为你必须改变你的代码,因为我已经知道如何制作一个过滤器,但如果你想我总是感激帮助=)我延迟回答,因为我不喜欢只使用ctrl+v,ctrl+c在我的代码中,而不了解每一行,我更喜欢看到每一行,了解如何以及为什么使用该部分。所以,不要生气,如果我耽搁了这么多时间来给你一个生命的迹象,呵呵,我只是学习和吸收,没有任何烦恼。看看我在另一个问题上发表的文章,我更深入地讨论了如何记录您的网络流量、查找API端点和模拟请求。我解决了我的问题,但我仍然看到并学习您的解析和链接。我非常感谢你帮助我
if c % 2 != 0:
column = 2
if c % 2 == 0:
line += 1
else:
line += 1
column = 1