Συζήτηση
Γεια χαρά, Επισκέπτης
Όνομα χρήστη: Κωδικός: Να με θυμάσαι

ΘΕΜΑ: UnicodeEncodeError σε script για download.

UnicodeEncodeError σε script για download. 10 Χρόνια 7 Μήνες πριν #2170

  • kamar
  • Το Άβαταρ του/της kamar
  • Αποσυνδεμένος
  • python
  • Δημοσιεύσεις: 409
  • Ληφθείσες Ευχαριστίες 88
Έχω αυτόν τον κώδικα, για κατέβασμα αρχείων (Python 3):
#!/usr/bin/env python3
#-*-coding: utf-8-*-
# filename: downloadme01.py
 
import urllib.request
import urllib.parse
import sys
 
def download_me(the_urls, block_size=8192):
    """Downloads a file from a site.
USAGE: python3 downloadme01.py http://1 http://2 ...
Author: 
License: GNU/GPL v 3.0
 
    """
 
    for the_url in the_urls: ## Αν έχουμε πάνω από μία διευθύνσεις δικτύου
        the_url = urllib.parse.unquote(the_url) ## Σβήνουμε αν υπάρχουν χαρακτήρες '%20f' κλπ.
        print(the_url)
        file_name = the_url.split('/')[-1] # Διαχωρίζουμε το αρχείο από τη διεύθυνση.
 
        site = urllib.request.urlopen(the_url) # Ανοίγουμε το αρχείο.
 
        file_size = int(site.getheader("Content-Length")) # Παίρνουμε το μήκος του αρχείου
 
 
        print("Κατεβάζω: {0} Bytes: {1} KBytes: {2:.2f}".format(file_name,\
                file_size, int(file_size/1024)))
 
        try:
            fh = open(file_name, 'wb') # Ανοίγουμε τοπικά θέση για να γράψουμε.
            megethos_arxeiou_kt = 0 # Αρχικό μέγεθος αρχείου 0 bytes.
 
            while True:
                buffer = site.read(block_size) # Διαβάζουμε 8192 bytes.
                if not buffer: # Αν δεν έχουμε να διαβάσουμε σταματάμε.
                    break
 
                megethos_arxeiou_kt += len(buffer) # Τι έχουμε κατεβάσει.
                fh.write(buffer) # Γράφουμε το αρχείο.
                prcnt = (megethos_arxeiou_kt / file_size) 
 
                katastasi = "{0:>6,d}kb {1:.2%}".format(round(megethos_arxeiou_kt/1024),\
                                                        prcnt)
                sys.stdout.write("\rΚατέβηκαν: " + katastasi)
                sys.stdout.flush()
 
            sys.stdout.write("\n")
 
        finally:
            fh.close()
 
if __name__ == '__main__':
    if len(sys.argv) > 1:
        del sys.argv[0]
        download_me(sys.argv)
    else:
        print("""Usage:
------
downloadme01.py http://url/to/the/file/file http://url/to/the/file/file2 ... or
python3 downloadme01.py http://url/to/the/file/file http://url/to/the/file/file2 ...
 
""")

ο οποίος λειτουργεί χωρίς πρόβλημα αν έχουμε url χωρίς ελληνικούς χαρακτήρες. Αν όμως υπάρχουν ελληνικοί χαρακτήρες (φαντάζομαι κυριλλικοί κλπ) βγάζει το παρακάτω μήνυμα:
km@asus:~$ python3 bin/downloadme01.py http://www.dw.de/popups/pdf/27169135-το-κείμενο-του-επεισοδίου-05-pdf.pdf
http://www.dw.de/popups/pdf/27169135-το-κείμενο-του-επεισοδίου-05-pdf.pdf
Traceback (most recent call last):
  File "bin/downloadme01.py", line 56, in <module>
    download_me(sys.argv)
  File "bin/downloadme01.py", line 22, in download_me
    site = urllib.request.urlopen(the_url) # Ανοίγουμε το αρχείο.
  File "/usr/lib/python3.3/urllib/request.py", line 160, in urlopen
    return opener.open(url, data, timeout)
  File "/usr/lib/python3.3/urllib/request.py", line 473, in open
    response = self._open(req, data)
  File "/usr/lib/python3.3/urllib/request.py", line 491, in _open
    '_open', req)
  File "/usr/lib/python3.3/urllib/request.py", line 451, in _call_chain
    result = func(*args)
  File "/usr/lib/python3.3/urllib/request.py", line 1272, in http_open
    return self.do_open(http.client.HTTPConnection, req)
  File "/usr/lib/python3.3/urllib/request.py", line 1252, in do_open
    h.request(req.get_method(), req.selector, req.data, headers)
  File "/usr/lib/python3.3/http/client.py", line 1061, in request
    self._send_request(method, url, body, headers)
  File "/usr/lib/python3.3/http/client.py", line 1089, in _send_request
    self.putrequest(method, url, **skips)
  File "/usr/lib/python3.3/http/client.py", line 953, in putrequest
    self._output(request.encode('ascii'))
UnicodeEncodeError: 'ascii' codec can't encode characters in position 25-26: ordinal not in range(128)

Δοκίμασα μερικά τρικ όπως quote και unquote αλλά δεν έχει αποτέλεσμα.
Κάθε βοήθεια δεκτή.
Γράφω σε Python 3
Τελευταία διόρθωση: 10 Χρόνια 7 Μήνες πριν από pmav99.
Πρέπει να είστε εγγεγραμμένο μέλος του Φόρουμ για να κάνετε μια δημοσίευση.

UnicodeEncodeError σε script για download. 10 Χρόνια 7 Μήνες πριν #2172

  • pmav99
  • Το Άβαταρ του/της pmav99
  • Αποσυνδεμένος
  • Author
  • Δημοσιεύσεις: 684
  • Ληφθείσες Ευχαριστίες 111
Το link που δίνεις, είσαι σίγουρος ότι είναι σωστό; Δεν κατεβάζει καποιο pdf γιατί...

Από εκεί και πέρα, δοκίμασε αν θέλεις με την requests

docs.python-requests.org/en/latest/index.html
import requests
 
url = """http://el.wikibooks.org/wiki/Linux_για_αρχάριους"""
 
response = requests.get(url)
print(response.ok)
print(response.text)
Τελευταία διόρθωση: 10 Χρόνια 7 Μήνες πριν από pmav99.
Πρέπει να είστε εγγεγραμμένο μέλος του Φόρουμ για να κάνετε μια δημοσίευση.
Οι ακόλουθοι χρήστες είπαν "Σε Ευχαριστώ": kamar

UnicodeEncodeError σε script για download. 10 Χρόνια 7 Μήνες πριν #2173

  • kamar
  • Το Άβαταρ του/της kamar
  • Αποσυνδεμένος
  • python
  • Δημοσιεύσεις: 409
  • Ληφθείσες Ευχαριστίες 88
Το link είναι σίγουρα σωστό. Αν το πατήσω σε Chromium ή Firefox κατεβαίνει.

Όσο για το requests, προσπαθώ να γράφω τα σκριπτ χωρίς τρίτες βιβλιοθήκες. Πάντως σ' ευχαριστώ.
Γράφω σε Python 3
Πρέπει να είστε εγγεγραμμένο μέλος του Φόρουμ για να κάνετε μια δημοσίευση.

UnicodeEncodeError σε script για download. 10 Χρόνια 7 Μήνες πριν #2174

  • pmav99
  • Το Άβαταρ του/της pmav99
  • Αποσυνδεμένος
  • Author
  • Δημοσιεύσεις: 684
  • Ληφθείσες Ευχαριστίες 111
!!!

Το ακόλουθο link δεν κατεβάζει τίποτα σε εμένα (firefox, ArchLinux, x64)
http://www.dw.de/popups/pdf/27169135-το-κείμενο-του-επεισοδίου-05-pdf.pdf
Αυτό μου λειτουργεί όμως...
http://www.dw.de/popups/pdf/27169135

H requests είναι πάντως πάρα πολύ καλή και βολική βιβλιοθήκη. Δεδομένου ότι είναι pure python, η εγκατάσταση της είναι πολύ εύκολη (pip install requests) και έτσι δε νομίζω ότι πρέπει να αποτελεί ανασταλτικό ρόλο για τη χρήση της. Ιδίως όταν λύνει προβλήματα :)

Επίσης αν όντως κατεβάζει το pdf, τότε μπορείς να δεις τον κώδικα της requests.get() για να δεις πως χειρίζεται το θέμα με τα encodings.

Για βοήθεια μπορείς να ρωτήσεις και στο #python στο freenode. Λογικά θα πάρεις άμεσα απάντηση.

Αν μπορείς ανέβασε και κάποιο άλλο link που και θα το ξαναδώ και εγώ.
Τελευταία διόρθωση: 10 Χρόνια 7 Μήνες πριν από pmav99.
Πρέπει να είστε εγγεγραμμένο μέλος του Φόρουμ για να κάνετε μια δημοσίευση.

UnicodeEncodeError σε script για download. 10 Χρόνια 7 Μήνες πριν #2175

  • kamar
  • Το Άβαταρ του/της kamar
  • Αποσυνδεμένος
  • python
  • Δημοσιεύσεις: 409
  • Ληφθείσες Ευχαριστίες 88
Δες αυτό το link: el.wikipedia.org/wiki/%CE%94%CE%B9%CE%B1...BB%CE%AC%CE%B4%CE%B1

Κατεβαίνει με wget, όχι όμως με το σκριπτ μου.

Όσο για το requests θα το δοκιμάσω σε virtualenv.
Γράφω σε Python 3
Πρέπει να είστε εγγεγραμμένο μέλος του Φόρουμ για να κάνετε μια δημοσίευση.

UnicodeEncodeError σε script για download. 10 Χρόνια 7 Μήνες πριν #2178

  • pmav99
  • Το Άβαταρ του/της pmav99
  • Αποσυνδεμένος
  • Author
  • Δημοσιεύσεις: 684
  • Ληφθείσες Ευχαριστίες 111
Το αρχικό link εξακολουθεί να μην μου παίζει. όσον αφορά τους unicode χαρακτήρες στα urls δες το εξής:
import urllib.parse as p
import urllib.request as r
 
# Κάνουμε escape με % όλους τους unicode χαρακτήρες
original_url = """http://el.wikibooks.org/wiki/Linux_για_αρχάριους"""
parsed_url = p.urlparse(original_url)
escaped_url = p.urljoin(original_url, p.quote(parsed_url.path))
 
# H wikipedia κάνει deny τα bots, οπότε πρέπει να προσποιηθούμε ότι είμαστε browser.
request = r.Request(escaped_url, headers={'User-Agent':'Mozilla/5.0'})
response = r.urlopen(request)
Τελευταία διόρθωση: 10 Χρόνια 7 Μήνες πριν από pmav99.
Πρέπει να είστε εγγεγραμμένο μέλος του Φόρουμ για να κάνετε μια δημοσίευση.

UnicodeEncodeError σε script για download. 10 Χρόνια 7 Μήνες πριν #2179

  • pmav99
  • Το Άβαταρ του/της pmav99
  • Αποσυνδεμένος
  • Author
  • Δημοσιεύσεις: 684
  • Ληφθείσες Ευχαριστίες 111
Ίσως είναι χρήσιμο να έχεις την urlopen μέσα σε try: except: block
docs.python.org/2/howto/urllib2.html#wrapping-it-up
Πρέπει να είστε εγγεγραμμένο μέλος του Φόρουμ για να κάνετε μια δημοσίευση.
Συντονιστές: pmav99
Χρόνος δημιουργίας σελίδας: 0.326 δευτερόλεπτα

Μοιράσου το!

Powered by CoalaWeb

Λίστα Ταχυδρομείου