[Python] Desde básico hasta avanzado: escenarios de aplicación de los módulos de solicitud de red urlib y reuests (12)

1.módulo urlib

urllib proporciona una serie de funciones para manipular URL.

1.Obtener solicitud

  • urllib request模块puede capturar fácilmente contenido URL, es decir, enviarlo GET请求a una página específica y luego devolver una respuesta HTTP:

Por ejemplo: rastrea Douban https://api.douban.com/v2/book/2129651y devuelve la respuesta:

from urllib import request

with request.urlopen('https://www.baidu.com') as f:
    data = f.read()
    print('Status:', f.status, f.reason)
    #响应头
    for k, v in f.getheaders():
        print('%s: %s' % (k, v))
    #响应数据    
    print('Data:', data.decode('utf-8'))

Puede ver los encabezados de respuesta HTTP y los datos JSON:

Status: 200 OK
Server: nginx
Date: Tue, 26 May 2015 10:02:27 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 2049
Connection: close
Expires: Sun, 1 Jan 2006 01:00:00 GMT
Pragma: no-cache
Cache-Control: must-revalidate, no-cache, private
X-DAE-Node: pidl1
Data: {
    
    "rating":{
    
    "max":10,"numRaters":16,"average":"7.4","min":0},"subtitle":"","author":["廖雪峰编著"],"pubdate":"2007-6",...}

Si queremos 模拟浏览器发送GET请求, necesitamos usar el objeto Solicitud. Al agregarlo al objeto Solicitud HTTP头, podemos agregarlo 请求伪装成浏览器. Por ejemplo 模拟iPhone 6去请求豆瓣首页:

from urllib import request

req = request.Request('http://www.douban.com/')
req.add_header('User-Agent', 'Mozilla/6.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/8.0 Mobile/10A5376e Safari/8536.25')
with request.urlopen(req) as f:
    print('Status:', f.status, f.reason)
    for k, v in f.getheaders():
        print('%s: %s' % (k, v))
    print('Data:', f.read().decode('utf-8'))

De esta forma, Douban devolverá la versión móvil de la página web apta para iPhone:

...
    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0">
    <meta name="format-detection" content="telephone=no">
    <link rel="apple-touch-icon" sizes="57x57" href="http://img4.douban.com/pics/cardkit/launcher/57.png" />
...

2.Solicitud de publicación

Si desea enviar una solicitud mediante POST, solo necesita pasar los datos del parámetro en bytes.

Simulamos un inicio de sesión en Weibo, primero leemos el correo electrónico y la contraseña de inicio de sesión, y luego username=xxx&password=xxxpasamos la codificación de acuerdo con el formato de la página de inicio de sesión de weibo.cn:

from urllib import request, parse

print('Login to weibo.cn...')
email = input('Email: ')
passwd = input('Password: ')
login_data = parse.urlencode([
    ('username', email),
    ('password', passwd),
    ('entry', 'mweibo'),
    ('client_id', ''),
    ('savestate', '1'),
    ('ec', ''),
    ('pagerefer', 'https://passport.weibo.cn/signin/welcome?entry=mweibo&r=http%3A%2F%2Fm.weibo.cn%2F')
])

req = request.Request('https://passport.weibo.cn/sso/login')
req.add_header('Origin', 'https://passport.weibo.cn')
req.add_header('User-Agent', 'Mozilla/6.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/8.0 Mobile/10A5376e Safari/8536.25')
req.add_header('Referer', 'https://passport.weibo.cn/signin/login?entry=mweibo&res=wel&wm=3349&r=http%3A%2F%2Fm.weibo.cn%2F')

with request.urlopen(req, data=login_data.encode('utf-8')) as f:
    print('Status:', f.status, f.reason)
    for k, v in f.getheaders():
        print('%s: %s' % (k, v))
    print('Data:', f.read().decode('utf-8'))

Si el inicio de sesión es exitoso, la respuesta que obtenemos es la siguiente:

Status: 200 OK
Server: nginx/1.2.0
...
Set-Cookie: SSOLoginState=1432620126; path=/; domain=weibo.cn
...
Data: {
    
    "retcode":20000000,"msg":"","data":{
    
    ...,"uid":"1658384301"}}

Si el inicio de sesión falla, la respuesta que obtenemos es la siguiente:

...
Data: {
    
    "retcode":50011015,"msg":"\u7528\u6237\u540d\u6216\u5bc6\u7801\u9519\u8bef","data":{
    
    "username":"[email protected]","errline":536}}

3.Agente

Si necesitamos un control más complejo, como acceder al sitio web a través de un Proxy, debemos usarlo.El ProxyHandlercódigo de muestra es el siguiente:

proxy_handler = urllib.request.ProxyHandler({
    
    'http': 'http://www.example.com:3128/'})
proxy_auth_handler = urllib.request.ProxyBasicAuthHandler()
proxy_auth_handler.add_password('realm', 'host', 'username', 'password')
opener = urllib.request.build_opener(proxy_handler, proxy_auth_handler)
with opener.open('http://www.example.com/login.html') as f:
    pass

4. Resumen

La función proporcionada por urllib es utilizar programas para realizar varias solicitudes HTTP. Si desea simular un navegador para completar una función específica, debe disfrazar la solicitud como un navegador. El método de camuflaje consiste en monitorear primero la solicitud enviada por el navegador y luego camuflarla según el encabezado de solicitud del navegador.El encabezado User-Agent se utiliza para identificar el navegador.

2. módulo de solicitudes

Ya hemos explicado el módulo urllib integrado de Python, que se utiliza para acceder a los recursos de la red. Sin embargo, es complicado de usar y carece de muchas funciones prácticas avanzadas.

Una mejor solución es utilizar solicitudes. Es una biblioteca de terceros de Python que es particularmente conveniente para procesar recursos URL.

1.Solicitudes de instalación

  • Si tiene instalado Anaconda (un administrador de paquetes gratuito y fácil de instalar), las solicitudes ya están disponibles. De lo contrario, deberás instalarlo mediante pip desde la línea de comando:

     pip install requests
    

Si Permission deniedla instalación falla, agregue sudo e inténtelo nuevamente.

2.Utilizar solicitudes

OBTENER solicitud

  • Una solicitud GET para acceder a una página requiere solo unas pocas líneas de código:

    import requests
    r = requests.get('https://www.douban.com/') # 豆瓣首页
    r.status_code
    #200
    r.text
    #'<!DOCTYPE HTML>\n<html>\n<head>\n<meta name="description" content="提供图书、电影、音乐唱片的推荐、评论和...'
    
  • Para URL con parámetros, pase uno dictcomo parámetro params:

    r = requests.get('https://www.douban.com/search', params={
          
          'q': 'python', 'cat': '1001'})
    
    r.url # 实际请求的URL
    #'https://www.douban.com/search?q=python&cat=1001'
    
  • Las solicitudes detectan automáticamente la codificación y se pueden encoding属性ver usando:

     r.encoding
     #'utf-8'
    
  • Independientemente de si la respuesta es texto o contenido binario, podemos content属性obtener el objeto bytes con:

     r.content
    #b'<!DOCTYPE html>\n<html>\n<head>\n<meta http-equiv="Content-Type" content="text/html; charset=utf-8">\n...'
    
  • La conveniencia de las solicitudes es que se pueden obtener directamente tipos específicos de respuestas, como JSON:

    r = requests.get('https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20weather.forecast%20where%20woeid%20%3D%202151330&format=json')
    r.json()
    #{'query': {'count': 1, 'created': '2017-11-17T07:14:12Z', ...
    
  • Cuando es necesario pasarlo HTTP Header, lo pasamos dictcomo parámetro de encabezados:

    r = requests.get('https://www.douban.com/', headers={
          
          'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit'})
    r.text
    #'<!DOCTYPE html>\n<html>\n<head>\n<meta charset="UTF-8">\n <title>豆瓣(手机版)</title>...'
    

Solicitud de publicación

  • Para enviar una solicitud POST, simplemente cambie el método get() a post() y luego pase el parámetro de datos como los datos de la solicitud POST:

    r = requests.post('https://accounts.douban.com/login', data={
          
          'form_email': '[email protected]', 'form_password': '123456'})
    
  • Las solicitudes utilizan application/x-www-form-urlencodedla codificación de datos POST de forma predeterminada. Si desea pasar datos JSON, puede pasar directamente el parámetro json:

    params = {
          
          'key': 'value'}
    r = requests.post(url, json=params) # 内部自动序列化为JSON
    
  • De manera similar, cargar archivos requiere un formato de codificación más complejo, pero las solicitudes lo simplifican a files参数:

    
    upload_files = {
          
          'file': open('report.xls', 'rb')}
    r = requests.post(url, files=upload_files)
    
  • Al leer un archivo, asegúrese de utilizarlo 'rb'即二进制模式读取para obtener bytes长度才la longitud del archivo.

Reemplace el método post() con put(), delete(), etc., y podrá solicitar recursos en modo PUT o DELETE.

  • Además de obtener fácilmente el contenido de la respuesta, las solicitudes también son muy sencillas de obtener otra información sobre la respuesta HTTP. Por ejemplo 获取响应头:

    r.headers
    #{Content-Type': 'text/html; charset=utf-8', 'Transfer-Encoding': 'chunked', 'Content-Encoding': 'gzip', ...}
    r.headers['Content-Type']
    #'text/html; charset=utf-8'
    

Galleta

  • Las solicitudes realizan un procesamiento especial para las cookies, de modo que podamos obtener fácilmente la cookie especificada sin analizar la cookie:

    r.cookies['ts']
    #'example_cookie_12345'
    
  • Para pasar cookies en la solicitud, simplemente prepare un dictparámetro de cookies entrantes:

    cs = {
          
          'token': '12345', 'status': 'working'}
    r = requests.get(url, cookies=cs)
    

horas extras

  • Para especificar un tiempo de espera, pase el parámetro de tiempo de espera en segundos:

     r = requests.get(url, timeout=2.5) # 2.5秒后超时
    

3. Resumen

  • Utilice solicitudes para obtener recursos URL, ¡así de simple!

Supongo que te gusta

Origin blog.csdn.net/qq877728715/article/details/132838450
Recomendado
Clasificación