URL не работает над кодом, но ручной поиск работает - PullRequest
0 голосов
/ 27 июня 2018

Я пытаюсь получить строковый ввод в моем коде 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, не имея возможности открывать веб-страницы, похожие на пользователя.

Ответы [ 2 ]

0 голосов
/ 28 июня 2018

На сайте есть несколько дополнительных требований, чтобы сделать подходящий запрос. Во-первых, он использует куки, поэтому требуется cookiejar. Это можно загрузить, сначала запросив домашнюю страницу, не выполняя поиск. Затем это также дает вам значение для _csrf, которое необходимо при отправке формы запроса. Наконец, запрос POST может быть сгенерирован из вашего поиска ввода с помощью urlencode() для правильного построения 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() - это просто быстрый способ получить определенные предметы из заданного списка.

0 голосов
/ 27 июня 2018

Хорошо, я не знаю, какая магия движет этим сайтом, но вы можете использовать браузер без головы и вместо того, чтобы искать песню в 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)
...