python - url 无法处理代码,但可以手动搜索

标签 python python-3.x url beautifulsoup urllib

我正在尝试将我的 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,但无法打开与用户相似的网页。

最佳答案

网站有一些额外的要求来提出合适的请求。首先它使用 cookie,所以 cookiejar是需要的。这可以通过首先请求主页而不进行搜索来加载。这还会为您提供提交请求表单时所需的 _csrf 值。最后,可以使用 urlencode() 从您的输入搜索中生成 POST 请求。正确构建q:

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() 只是一种从给定列表中获取特定项目的快速方法。

关于python - url 无法处理代码,但可以手动搜索,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51069581/

相关文章:

python - 自动更新 pandas 中的列?

python - Django 网址 : optional argument with default value is always None

python - Python3中Elasticsearch .search对象返回错误

linux - 如何使用 GTK、python 和 glade 制作单窗口程序?

php - 为什么 codeIgniter 显示请求的 URL 在此服务器上找不到?

javascript - 只获取 FileStack JSON.stringify 的 url 值?

javascript - 对 django View 的 Ajax 请求未返回响应

python-3.x - 在PyCharm中配置解释器: “please use a different SDK name”

python - 我们如何合并多个图?

url - TYPO3 URL 处理顺序