El urllib2 de Python sigue los redireccionamientos 3xx para obtener el contenido final. ¿Hay alguna manera de hacer que urllib2 (o alguna otra biblioteca como httplib2) también siga a meta refreshes? ¿O necesito analizar el HTML manualmente para las meta etiquetas de actualización?cómo seguir actualizaciones de metadatos en Python
Respuesta
bien, parece que no hay biblioteca es compatible con él, así que he estado utilizando este código:
import urllib2
import urlparse
import re
def get_hops(url):
redirect_re = re.compile('<meta[^>]*?url=(.*?)["\']', re.IGNORECASE)
hops = []
while url:
if url in hops:
url = None
else:
hops.insert(0, url)
response = urllib2.urlopen(url)
if response.geturl() != url:
hops.insert(0, response.geturl())
# check for redirect meta tag
match = redirect_re.search(response.read())
if match:
url = urlparse.urljoin(url, match.groups()[0].strip())
else:
url = None
return hops
Utilice BeautifulSoup o lxml para analizar el código HTML.
usando un analizador de HTML que acaba de extraer la etiqueta meta de actualización es un exceso , al menos para mis propósitos. Esperaba que hubiera una biblioteca de Python HTTP que hiciera esto automáticamente. – hoju
Bien 'meta' it * es * una etiqueta html, por lo que es poco probable que encuentre esta funcionalidad en una biblioteca http. –
que aquí hay una solución utilizando httplib2 (y la autenticación de certificados basados) BeautifulSoup y:
import BeautifulSoup
import httplib2
def meta_redirect(content):
soup = BeautifulSoup.BeautifulSoup(content)
result=soup.find("meta",attrs={"http-equiv":"Refresh"})
if result:
wait,text=result["content"].split(";")
if text.strip().lower().startswith("url="):
url=text[4:]
return url
return None
def get_content(url, key, cert):
h=httplib2.Http(".cache")
h.add_certificate(key,cert,"")
resp, content = h.request(url,"GET")
# follow the chain of redirects
while meta_redirect(content):
resp, content = h.request(meta_redirect(content),"GET")
return content
Una similares solución utilizando las solicitudes y las bibliotecas lxml. También hace una simple comprobación de que lo que se prueba es en realidad HTML (un requisito en mi implementación). También es capaz de capturar y usar cookies mediante el uso de las sesiones de la biblioteca de solicitudes (algunas veces es necesario si se usa la redirección + cookies como un mecanismo anti raspado).
import magic
import mimetypes
import requests
from lxml import html
from urlparse import urljoin
def test_for_meta_redirections(r):
mime = magic.from_buffer(r.content, mime=True)
extension = mimetypes.guess_extension(mime)
if extension == '.html':
html_tree = html.fromstring(r.text)
attr = html_tree.xpath("//meta[translate(@http-equiv, 'REFSH', 'refsh') = 'refresh']/@content")[0]
wait, text = attr.split(";")
if text.lower().startswith("url="):
url = text[4:]
if not url.startswith('http'):
# Relative URL, adapt
url = urljoin(r.url, url)
return True, url
return False, None
def follow_redirections(r, s):
"""
Recursive function that follows meta refresh redirections if they exist.
"""
redirected, url = test_for_meta_redirections(r)
if redirected:
r = follow_redirections(s.get(url), s)
return r
Uso:
s = requests.session()
r = s.get(url)
# test for and follow meta redirects
r = follow_redirections(r, s)
Algunas veces los redireccionamientos de actualización de meta apuntan a URL relativas. Por ejemplo, Facebook tiene ''. Sería bueno detectar URL relativas y anteponer el esquema y el host. –
@JosephMornin: Adaptado. Me di cuenta de que aún no admite redirecciones circulares, aunque ... siempre algo. – mlissner
Si no desea utilizar bs4, puede utilizar lxml así:
from lxml.html import soupparser
def meta_redirect(content):
root = soupparser.fromstring(content)
result_url = root.xpath('//meta[@http-equiv="refresh"]/@content')
if result_url:
result_url = str(result_url[0])
urls = result_url.split('URL=') if len(result_url.split('url=')) < 2 else result_url.split('url=')
url = urls[1] if len(urls) >= 2 else None
else:
return None
return url
- 1. ¿Cómo puedo seguir las actualizaciones de un módulo de CPAN en particular?
- 2. Metadatos de video utilizando python
- 3. Escribir metadatos personalizados complejos en imágenes a través de python
- 4. Scrapy Crawler en python no puede seguir los enlaces?
- 5. Mecanizar - Cómo seguir o "hacer clic" Meta actualizar en raíles
- 6. Cómo obtener metadatos de imagen en ios
- 7. Cómo programar actualizaciones de índice en CouchDB
- 8. cómo recuperar metadatos de shoutcast en android?
- 9. ¿Cómo extraer metadatos de mp3?
- 10. Cómo seguir un archivo en git
- 11. Establecer metadatos en iTextSharp
- 12. ¿Cómo seguir un enlace en QWebKit?
- 13. Automatizando wix pequeñas actualizaciones y actualizaciones menores
- 14. Cómo cambiar los metadatos en un objeto en Amazon S3
- 15. ¿Cómo funcionan las actualizaciones en tiempo real?
- 16. ¿Seguir un archivo en Clojure?
- 17. actualizaciones instantáneas de maven
- 18. Obtener metadatos de MPMoviePlayerController
- 19. Múltiples actualizaciones en MySQL
- 20. WCF ¿Cómo habilitar los metadatos?
- 21. Accediendo a los propios metadatos del huevo python
- 22. ¿Cómo enviar actualizaciones parciales RESTful?
- 23. Python: Usando Hachoir, ¿cómo se extraen metadatos para objetos similares a archivos?
- 24. Cómo recuperar metadatos de secuencias de JDBC?
- 25. RSS Actualizaciones de artículos
- 26. metadatos personalizados en AS3/Flex?
- 27. Contenedor de metadatos php FFmpeg
- 28. ¿Cómo obtener metadatos de una imagen?
- 29. ¿Cómo puedo acelerar las actualizaciones de SVN?
- 30. Cómo obtener actualizaciones antiguas de CE 6.0
Este funciona muy bien, gracias por publicarlo. – Yehonatan