web-dev-qa-db-fra.com

Python 3.6: TypeError: un objet de type octet est requis, pas "str" ​​lors de la tentative d'impression de tous les liens d'une page.

J'assiste à un cours en ligne sur Python pour les débutants. Le cours a expliqué comment imprimer tous les liens dans le code source d'une page Web. J'ai écrit les codes pour cela à l'aide de Notepad ++, puis les ai collés dans l'interpréteur Python (Python 3.6 sous Windows). 

def get_next_target(page):
    start_link=page.find('<a href=')
    if start_link==-1:
        return None,0
    start_quote=page.find('"',start_link)
    end_quote=page.find('"',start_quote+1)
    url=page[start_quote+1,end_quote]
    return url,end_quote

def print_all_links(page):
    while True:
        url,endpos=(get_next_target(page))
        if url:
            print(url)
            page=page[endpos:]
        else:
            break

def get_page(url):
    import urllib.request
    return urllib.request.urlopen(url).read()

print_all_links(get_page('https://youtube.com'))

Après avoir appuyé sur Entrée, j'ai eu ceci:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in print_all_links
  File "<stdin>", line 2, in get_next_target
TypeError: a bytes-like object is required, not 'str'

Je ne peux pas comprendre ce qui ne va pas avec mes codes.

4
failbetter

Le bogue survient parce que vous appelez urlopen.read qui renvoie un objet bytes. Vous essayez ensuite de rechercher cette chaîne bytest avecstrchaînes de recherche, ce qui provoque l'erreur.

Heureusement, la solution est vraiment petite. Appelez bytes.decode pour convertir la bytes en un objet str.

import urllib.request

def get_page(url):    
    url = urllib.request.urlopen(url)
    return url.read().decode('utf-8')

En outre, je vous recommande d'importer tous les modules requis une fois , en haut de votre script.

3
coldspeed

Le problème est que vous devez décoder la sortie read():

return urllib.request.urlopen(url).read().decode('utf-8')

En outre, vous avez une petite faute de frappe dans la ligne suivante (, où vous vouliez probablement dire :):

url = page[start_quote+1:end_quote]
2
grovina

Je recommande d'utiliser le paquet request au lieu de urllib. Vous pouvez vous référer au code ci-dessous:

from bs4 import BeautifulSoup
import requests
url = "http://douban.com"
r  = requests.get(url) 
data = r.text
soup = BeautifulSoup(data)

for link in soup.find_all('a'):
   print link.get("href")
0
Bhushan Pant