Удлинитель URL-адресов с использованием libcurl: проблемы с IRI/IDN и фрагментами

Я пытаюсь закодировать удлинитель URL-адреса, используя libcurl через pycURL (если вы не знаете, что pycURL не уходит, это проблема libcurl). чтобы получить конечный URL-адрес без какого-либо перенаправления, чтобы мы могли получить реальный домен ссылки.
Вот код, показывающий, что я пытаюсь сделать:

#!/usr/bin/python
# -*- coding: utf-8 -*-

import os
import sys
import pycurl 
import urllib    

url="https://t.co/0u0Jb2Pw7k" #Wikipedia Colonne Vendôme

c = pycurl.Curl()
c.setopt(pycurl.URL, url)
c.setopt(pycurl.FOLLOWLOCATION, 1) # Allow URL elongation
c.setopt(pycurl.SSL_VERIFYHOST, 0)
c.setopt(pycurl.SSL_VERIFYPEER, 0)
c.setopt(pycurl.MAXREDIRS, 25)
c.setopt(pycurl.AUTOREFERER, 1)
c.setopt(pycurl.WRITEFUNCTION, lambda x: None) # No output of body. Don't care
c.setopt(pycurl.HEADER, 1) # For debug only
c.setopt(pycurl.VERBOSE, 1) # For debug only
c.setopt(pycurl.USERAGENT, "Opera/12.02 (X11; Linux i686; Opera Cqcb Style; U; fr-FR) Presto/2.9.201 Version/12.02/AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu")
c.setopt(pycurl.REFERER, url)

try:
    c.perform()
except:
    pass
print c.getinfo(pycurl.HTTP_CODE) , c.getinfo(pycurl.EFFECTIVE_URL)

Есть несколько проблем:

  1. libcURL не может обрабатывать IRI или IDN. В случае, указанном в приведенном выше коде, URL-адрес должен быть удлинен до https://fr.wikipedia.org/wiki/Colonne_Vendôme, но libcurl возвращает https://fr.wikipedia.org/wiki/Colonne_Vend￴me. Я думаю, вы видите разницу. Я знаю, что эти URL-адреса не соответствуют RFC, но они находятся в свободном доступе, поэтому я должен иметь возможность управлять ими. Итак, мои вопросы:
    Есть ли способ заставить libcURL понимать эти URL? Есть ли способ заставить кодировку? Есть ли способ работать между запросами на кодирование URL?

  2. Также есть проблема с URL-фрагментом или привязкой (#). Если конечный URL-адрес содержит фрагмент, libcurl обрезает его перед возвратом ответа. Это имеет смысл с точки зрения HTTP, потому что на сервер не нужно отправлять фрагменты, но, конечно, мне нужна эта часть. Не потому, что якорь важен, а потому, что если этот URL http://goo.gl/I8AYpW удлинить до https://groups.google.com/forum/, он абсолютно бесполезен. Итак, мои вопросы:
    Есть ли способ получить фрагмент в конце? Есть ли способ получить последний запрошенный URL (так, с фрагментом)? Еще раз, есть ли способ работать между запросами, чтобы сохранить окончательный фрагмент?

  3. Есть несколько сайтов, которые плохо работают с этим типом элонгатора. Такие сайты:
    http://t.co/Gej1JY3sgf возвращают HTTP 301 с пустым ответом, но работают в браузере
    http://t.co/3Ek7U438Ee возвращают HTTP 303, но работают в браузере
    http://tinyurl.com/lvyapao не удлиняются (как любой тиниурл).< br> Есть ли у вас какие-либо советы или подсказки по этому поводу?

Что я ищу, так это делать хороший код. Так что я не люблю временные промежутки, но если нет другого решения, я воспользуюсь ими. Если вы скажете мне, что есть лучший способ сделать это, чем libcurl, я могу отказаться от pycURL. Но я не могу отказаться от Python.

Так что, если у вас есть что-нибудь, я возьму это. Я понятия не имею, что делать сейчас.

РЕДАКТИРОВАТЬ :

Наконец, обновление:

  1. Для этого была проблема безопасности в Твиттере. Я пытался удлинить URL-адреса t.co, но Twitter не возвращал тот же URL-адрес, если вы использовали wget/curl/etc. вещи по сравнению с вещами HTTP/JS. Поскольку это была проблема безопасности, я выиграл награду, но не мог говорить об этом до недели назад: https://hackerone.com/reports/34084

  2. Для этого ответ ниже решил мою проблему. Вот почему он выиграл его.

  3. Для этого нет глобального решения, так как с этим нужно обращаться в каждом конкретном случае.


person Cqoicebordel    schedule 28.10.2014    source источник
comment
Позвольте мне быть первым, кто поприветствует вас на SO и поаплодирует вашему хорошо сформулированному вопросу. Однако я действительно не вижу, что вы пытаетесь сделать здесь. Получить перенаправленный URL?   -  person RickyA    schedule 28.10.2014
comment
Благодарю вас ! Да, я пытаюсь получить полный URL-адрес, конечный URL-адрес без перенаправления. Цель состоит в том, чтобы узнать реальный домен ссылки, прежде чем щелкнуть по ней (в приложении с помощью кода, показанного выше). Я отредактирую свой пост.   -  person Cqoicebordel    schedule 28.10.2014


Ответы (1)


Этот материал libcurl не выглядит так, как будто он собирается добиться цели. Я бы использовал пакет запросы:

import requests

bla = requests.head("https://t.co/0u0Jb2Pw7k", allow_redirects=True)

print(bla)
print(bla.url)

>> <Response [404]>
>> https://fr.wikipedia.org/wiki/Colonne_Vend%EF%BF%B4me
person RickyA    schedule 28.10.2014
comment
Хм... Кажется, это не работает по-вашему: у вас должен быть ответ 200, а URL-адрес не работает в браузере. Но я посмотрю requests, может там есть ответ. - person Cqoicebordel; 28.10.2014
comment
Но это работает для части фрагмента. Это шаг в правильном направлении! - person Cqoicebordel; 28.10.2014
comment
Извините за долгое время без ответа, но прочитайте мое редактирование выше по (хорошей) причине :) - person Cqoicebordel; 16.08.2015