Qual é a maneira mais rápida de obter HTTP HTTP em Python?


613

Qual é a maneira mais rápida de obter HTTP HTTP em Python se eu souber que o conteúdo será uma string? Estou pesquisando na documentação por uma única linha rápida, como:

contents = url.get("http://example.com/foo/bar")

Mas tudo o que consigo encontrar usando o Google é httplibe urllib- e não consigo encontrar um atalho nessas bibliotecas.

O Python 2.5 padrão possui um atalho de alguma forma, como acima, ou devo escrever uma função url_get?

  1. Eu preferiria não capturar a saída do bombardeio para wgetou curl.

Eu encontrei o que precisava aqui: stackoverflow.com/a/385411/1695680
ThorSummoner

Respostas:


872

Python 3:

import urllib.request
contents = urllib.request.urlopen("http://example.com/foo/bar").read()

Python 2:

import urllib2
contents = urllib2.urlopen("http://example.com/foo/bar").read()

Documentação para urllib.requeste read.


44
Tudo fica bem limpo? Parece que eu deveria ligar para closevocê read. Isso é necessário?
Frank Krueger

4
É uma boa prática fechá-lo, mas se você estiver procurando por uma linha única, poderá omitir. :-) #
22640 Nick Presta #:

28
O objeto retornado pelo urlopen será excluído (e finalizado, que o fecha) quando ficar fora do escopo. Como o Cpython é contado como referência, você pode contar com isso acontecendo imediatamente após o read. Mas um withbloco seria mais clara e mais seguro para Jython, etc.
sah

8
Não funciona com sites somente HTTPS. requestsfunciona bem
OverCoder

6
Se você estiver usando o Amazon Lambda e precisar obter um URL, a solução 2.x estará disponível e embutida. Parece funcionar com https também. Não é nada mais do que r = urllib2.urlopen("http://blah.com/blah")e então text = r.read(). É sincronização, apenas espera pelo resultado em "texto".
Fattie

412

Você pode usar uma biblioteca chamada solicitações .

import requests
r = requests.get("http://example.com/foo/bar")

Isso é bem fácil. Então você pode fazer assim:

>>> print(r.status_code)
>>> print(r.headers)
>>> print(r.content)

1
@JoeBlow lembre-se de que você deve importar as bibliotecas externas para usá-las
MikeVelazco

1
Quase qualquer biblioteca Python pode ser usada no AWS Lambda. Para Python puro, você só precisa "vender" essa biblioteca (copie para as pastas do módulo em vez de usar pip install). Para bibliotecas não puras, há uma etapa extra - você precisa fazer pip installa lib em uma instância do AWS Linux (a mesma lambda de variante do SO executada) e depois copiar esses arquivos para obter compatibilidade binária com o AWS Linux. As únicas bibliotecas que você nem sempre poderá usar no Lambda são aquelas com apenas distribuições binárias, que felizmente são muito raras.
Chris Johnson

6
@lawphotog isso funciona com python3, mas você precisa pip install requests.
akarilimano

Mesmo a biblioteca padrão urllib2 recomenda pedidos
Asfand Qazi

Em relação ao Lambda: se você deseja usar solicitações nas funções do AWS Lambda. Também existe uma biblioteca de solicitações boto3 pré-instalada. from botocore.vendored import requests Uso response = requests.get('...')
kmjb 21/08/19

29

Se você deseja que a solução com o Activplib2 seja oneliner, considere instanciar um objeto Http anônimo

import httplib2
resp, content = httplib2.Http().request("http://example.com/foo/bar")

19

Dê uma olhada no httplib2 , que - ao lado de muitos recursos muito úteis - fornece exatamente o que você deseja.

import httplib2

resp, content = httplib2.Http().request("http://example.com/foo/bar")

Onde o conteúdo seria o corpo da resposta (como uma string) e o resp conteria os cabeçalhos de status e resposta.

No entanto, ele não vem incluído em uma instalação python padrão (mas requer apenas python padrão), mas definitivamente vale a pena conferir.


6

É simples o suficiente com os poderosos urllib3 biblioteca.

Importe-o assim:

import urllib3

http = urllib3.PoolManager()

E faça uma solicitação como esta:

response = http.request('GET', 'https://example.com')

print(response.data) # Raw data.
print(response.data.decode('utf-8')) # Text.
print(response.status) # Status code.
print(response.headers['Content-Type']) # Content type.

Você também pode adicionar cabeçalhos:

response = http.request('GET', 'https://example.com', headers={
    'key1': 'value1',
    'key2': 'value2'
})

Mais informações podem ser encontradas na documentação do urllib3 .

urllib3é muito mais seguro e fácil de usar do que o módulo urllib.requestou httpmódulos internos e é estável.


1
ótimo para o fato de que você pode facilmente fornecer um verbo HTTP
Tom

5

A solução do wget para o wget é realmente útil, no entanto, descobri que não imprime o progresso durante o processo de download. É perfeito se você adicionar uma linha após a declaração de impressão no reporthook.

import sys, urllib

def reporthook(a, b, c):
    print "% 3.1f%% of %d bytes\r" % (min(100, float(a * b) / c * 100), c),
    sys.stdout.flush()
for url in sys.argv[1:]:
    i = url.rfind("/")
    file = url[i+1:]
    print url, "->", file
    urllib.urlretrieve(url, file, reporthook)
print

4

Aqui está um script wget no Python:

# From python cookbook, 2nd edition, page 487
import sys, urllib

def reporthook(a, b, c):
    print "% 3.1f%% of %d bytes\r" % (min(100, float(a * b) / c * 100), c),
for url in sys.argv[1:]:
    i = url.rfind("/")
    file = url[i+1:]
    print url, "->", file
    urllib.urlretrieve(url, file, reporthook)
print

4

Sem mais importações necessárias, esta solução funciona (para mim) - também com https:

try:
    import urllib2 as urlreq # Python 2.x
except:
    import urllib.request as urlreq # Python 3.x
req = urlreq.Request("http://example.com/foo/bar")
req.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36')
urlreq.urlopen(req).read()

Frequentemente, tenho dificuldade em capturar o conteúdo quando não especifico um "User-Agent" nas informações do cabeçalho. Normalmente, os pedidos são cancelados com algo como: urllib2.HTTPError: HTTP Error 403: Forbiddenou urllib.error.HTTPError: HTTP Error 403: Forbidden.


4

Como também enviar cabeçalhos

Python 3:

import urllib.request
contents = urllib.request.urlopen(urllib.request.Request(
    "https://api.github.com/repos/cirosantilli/linux-kernel-module-cheat/releases/latest",
    headers={"Accept" : 'application/vnd.github.full+json"text/html'}
)).read()
print(contents)

Python 2:

import urllib2
contents = urllib2.urlopen(urllib2.Request(
    "https://api.github.com",
    headers={"Accept" : 'application/vnd.github.full+json"text/html'}
)).read()
print(contents)

2

Se você estiver trabalhando especificamente com APIs HTTP, também há opções mais convenientes, como Nap .

Por exemplo, veja como obter dicas do Github desde 1º de maio de 2014 :

from nap.url import Url
api = Url('https://api.github.com')

gists = api.join('gists')
response = gists.get(params={'since': '2014-05-01T00:00:00Z'})
print(response.json())

Mais exemplos: https://github.com/kimmobrunfeldt/nap#examples


2

Excelentes soluções Xuan, Theller.

Para que ele funcione com o python 3, faça as seguintes alterações

import sys, urllib.request

def reporthook(a, b, c):
    print ("% 3.1f%% of %d bytes\r" % (min(100, float(a * b) / c * 100), c))
    sys.stdout.flush()
for url in sys.argv[1:]:
    i = url.rfind("/")
    file = url[i+1:]
    print (url, "->", file)
    urllib.request.urlretrieve(url, file, reporthook)
print

Além disso, o URL digitado deve ser precedido por um "http: //", caso contrário, ele retornará um erro de tipo de URL desconhecido.


1

Para python >= 3.6, você pode usar o dload :

import dload
t = dload.text(url)

Para json:

j = dload.json(url)

Instalar:
pip install dload


0

Na verdade, em python, podemos ler URLs como arquivos, aqui está um exemplo para ler json da API.

import json

from urllib.request import urlopen

with urlopen(url) as f:

resp = json.load(f)

return resp['some_key']

Apesar de agradecermos sua resposta, seria melhor se ela fornecesse valor adicional além das outras respostas. Nesse caso, sua resposta não fornece valor adicional, pois outro usuário já postou essa solução. Se uma resposta anterior foi útil para você, vote em vez de repetir a mesma informação.
Toby Speight

0

Se você deseja uma API de nível inferior:

import http.client

conn = http.client.HTTPSConnection('example.com')
conn.request('GET', '/')

resp = conn.getresponse()
content = resp.read()

conn.close()

text = content.decode('utf-8')

print(text)
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.