2016-08-14 2 views
1

Ситуация: Я выскабливание один сайт, URL-адреса для страниц по той же схеме:Python URLLIB исключение юникода в 302 перенаправлении

http://www.pageadress/somestuff/ID-HERE/ 

Ничего необычного. У меня много идентификаторов, которые мне нужно очистить, и большинство из них работают правильно. Однако страница ведет себя как портал. В браузере, при вводе такого адреса, вы попадаете на:

http://www.pageadress/somestuff/ID-HERE-title_of_subpage 

Что может быть проблематичным является то, что иногда это название может содержать не-ASCII символы (примерно 0,01% случаев), поэтому (я думаю, что это вопрос) я получаю исключение:

File "/usr/lib/python3.4/urllib/request.py", line 161, in urlopen 
    return opener.open(url, data, timeout) 
    File "/usr/lib/python3.4/urllib/request.py", line 469, in open 
    response = meth(req, response) 
    File "/usr/lib/python3.4/urllib/request.py", line 579, in http_response 
    'http', request, response, code, msg, hdrs) 
    File "/usr/lib/python3.4/urllib/request.py", line 501, in error 
    result = self._call_chain(*args) 
    File "/usr/lib/python3.4/urllib/request.py", line 441, in _call_chain 
    result = func(*args) 
    File "/usr/lib/python3.4/urllib/request.py", line 684, in http_error_302 
    return self.parent.open(new, timeout=req.timeout) 
    File "/usr/lib/python3.4/urllib/request.py", line 463, in open 
    response = self._open(req, data) 
    File "/usr/lib/python3.4/urllib/request.py", line 481, in _open 
    '_open', req) 
    File "/usr/lib/python3.4/urllib/request.py", line 441, in _call_chain 
    result = func(*args) 
    File "/usr/lib/python3.4/urllib/request.py", line 1210, in http_open 
    return self.do_open(http.client.HTTPConnection, req) 
    File "/usr/lib/python3.4/urllib/request.py", line 1182, in do_open 
    h.request(req.get_method(), req.selector, req.data, headers) 
    File "/usr/lib/python3.4/http/client.py", line 1088, in request 
    self._send_request(method, url, body, headers) 
    File "/usr/lib/python3.4/http/client.py", line 1116, in _send_request 
    self.putrequest(method, url, **skips) 
    File "/usr/lib/python3.4/http/client.py", line 973, in putrequest 
    self._output(request.encode('ascii')) 
UnicodeEncodeError: 'ascii' codec can't encode characters in position 38-39: ordinal not in range(128). 

Странная вещь, что не юникод символов в URL я перенаправлены не на самом деле на позиции 38-39, но есть и на других. используется

Код:

import socket 
import urllib.parse 
import urllib.request 
socket.setdefaulttimeout(30) 
url = "https://www.bettingexpert.com/archive/tip/3207221" 
headers = {'User-Agent': 'Mozilla/5.0'} 
content = urllib.request.urlopen(urllib.request.Request(url, None, headers)).read().decode('utf-8') 

Любой способ обойти это, желательно без использования других библиотек?

// О, славный мир питона, создающий 1000 проблем, я даже не подумал бы, если бы я писал в рубине.

+0

Код, который вы предоставляете, не является полным (не может быть выполнен). Какова ценность 'id'? Тот же вопрос для фактического URL (который здесь не указан). Если вы хотите, чтобы другие могли отлаживать проблему, вам необходимо предоставить реальный URL-адрес. –

+1

Вы пытались использовать 'urllib.parse.quote (id .__ str __())' вместо простого 'id .__ str __()'? – Phillip

+0

Id - целое число @Phillip – piezol

ответ

0

Итак, я нашел решение своей конкретной проблемы. Я только что собрал оставшуюся часть «url» из их api, и после некоторых незначительных преобразований я могу получить доступ к странице без каких-либо перенаправлений. Это, конечно, не означает, что я решил общую проблему - он может появиться позже в будущем, поэтому я разработал «решение».

Публикуя этот код здесь, я в основном гарантировал себе, что я никогда не буду работать программистом, поэтому не смотрите на него, если вы едите.

«Капибара» необходим драгоценный камень и полтергейст, потому что почему бы и нет?

#test.py 
import socket 
import urllib.parse 
import urllib.request 
import os 
tip_id = 3207221 
socket.setdefaulttimeout(30) 
url = "http://www.bettingexpert.com/archive/tip/" + tip_id.__str__() 
headers = {'User-Agent': 'Mozilla/5.0'} 

try: 
    content = urllib.request.urlopen(urllib.request.Request(url, None, headers)).read().decode('utf-8') 
except UnicodeEncodeError: 
    print("Overkill activated") 
    os.system('ruby test.rb ' + tip_id.__str__()) 
    with open(tip_id.__str__(), 'r') as file: 
     content = file.read() 
    os.remove(tip_id.__str__()) 
print(content) 

.

#test.rb 
require 'capybara' 
require 'capybara/dsl' 
require 'capybara/poltergeist' 

Capybara.register_driver :poltergeist_no_timeout do |app| 
    driver = Capybara::Poltergeist::Driver.new(app, timeout: 30) 
    driver.browser.url_blacklist = %w(
    http://fonts.googleapis.com 
    http://html5shiv.googlecode.com 
) 
    driver 
end 
Capybara.default_driver = :poltergeist_no_timeout 
Capybara.run_server = false 
include Capybara::DSL 
begin 
    page.reset_session! 
    page.visit("http://www.bettingexpert.com/archive/tip/#{ARGV[0]}") 
rescue 
    retry 
end 
File.open(ARGV[0], 'w') do |file| 
    file.print(page.html) 
end 
Смежные вопросы