我正在尝试在我的python代码中输入字符串,以将其转换并实现为URL以在网站上搜索该字符串。我正在使用的网站是songbpm.com,而我想要搜索的是歌曲,并且我收到了歌曲的播放速度。在HTML中找到相关信息不是问题,我已经完成了此工作,并且我的url创建正常了,在这里:
import urllib.request
import urllib.parse
song = input("")
fin = ""
for i in song:
if i == "(":
tempone = song
song = tempone.split("(")[0] + tempone.split(") ")[1]
previous = ""
for i in song:
if i.isalpha():
temp = fin
fin = temp + i
else:
if previous.isalpha():
temp = fin
fin = temp + "-"
previous = i
songencoded = urllib.parse.quote(song, safe='')
print('https://songbpm.com/'+ fin.lower() + '?q=' + songencoded)
response = urllib.request.urlopen('https://songbpm.com/'+ fin.lower() + '?q=' + songencoded)
text = str(response.read()).split('\\n')
返回的URL与我在网站上手动输入搜索输入时的URL相同,但是,当我运行此代码时,它将始终读取html数据以进行无结果重定向。
此外,如果我将计算机生成的URL粘贴到浏览器中,则会重定向到无结果页面,但是,在浏览器中手动搜索相同的字符串后,计算机生成的URL也可以正常工作(重试时)
我还观察到,手动打开某个URL后,我可以使用相同的搜索查询运行该代码,并且可以正常工作-如果用户(而不是用户)似乎将搜索缓存了一段时间。代码打开它。
我如何解决此代码问题,尽管生成确切的URL,但无法打开与用户相似的网页。
答案 0 :(得分:3)
好吧,我不知道该网站是由哪种魔力驱动的,但是您可以使用无头浏览器,而不是在URL中查找歌曲,您可以输入要查找的歌曲的名称搜索框,它将起作用!抱歉,我没有正确回答您的问题
这是100%正常工作的代码:)玩得开心
import bs4
import time
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
options =webdriver.ChromeOptions()
options.add_argument('headless')
driver = webdriver.Chrome(chrome_options = options)
url = ('https://songbpm.com/')
while True:
driver.get(url)
inputElement = driver.find_element_by_id("search-field")
inputElement.send_keys(str(input("Enter name of a song: \n>")))
inputElement.send_keys(Keys.ENTER)
html = driver.page_source
soup= bs4.BeautifulSoup(html, "html.parser")
for node in soup.findAll("a", {"class": "media"}):
print("ARTIST:",node.find("p", {"class":"artist-name"}).text.strip())
print("SONG:",node.find("p", {"class": "track-name"}).text.strip())
print("*"*20)
答案 1 :(得分:3)
该网站还有一些其他要求才能提出合适的要求。首先,它使用cookie,因此需要cookiejar
。可以通过首先请求主页而不进行搜索来加载。然后,这还会为您提供_csrf
的值,该值是提交请求表单时所需的。最后,通过使用urlencode()
正确构建q
,可以从输入搜索中生成POST请求:
from operator import itemgetter
from bs4 import BeautifulSoup
import http.cookiejar
import urllib.request
import urllib.parse
song = input('Enter song: ')
cookie_jar = http.cookiejar.CookieJar()
cookie_processor = urllib.request.HTTPCookieProcessor(cookie_jar)
opener = urllib.request.build_opener(cookie_processor)
with opener.open('https://songbpm.com') as response:
html_1 = response.read().decode('utf-8')
soup_1 = BeautifulSoup(html_1, 'html.parser')
data = urllib.parse.urlencode({'q' : song, '_csrf' : soup_1.input['value']}).encode('ascii')
with opener.open('https://songbpm.com/searches', data) as response:
html_2 = response.read().decode('utf-8')
soup_2 = BeautifulSoup(html_2, 'html.parser')
for a in soup_2.find_all('a', {'class' : 'media'}):
print(', '.join(itemgetter(0, 1, 4)([p.get_text(strip=True) for p in a.find_all('p')])))
哪个会给您以下结果:
Enter song: clean bandit - solo
Clean Bandit, Solo (feat. Demi Lovato), 105
Clean Bandit, Solo (feat. Demi Lovato) - Acoustic, 0
Clean Bandit, Solo (feat. Demi Lovato) - Ofenbach Remix, 121
Clean Bandit, Solo (feat. Demi Lovato) - Sofi Tukker Remix, 127
Clean Bandit, Solo (feat. Demi Lovato) - Wideboys Remix, 122
使用beautifulsoup
可以轻松提取所有细节。 itemgetter()
只是从给定列表中获取某些物品的快速方法。