O mais completo da história! Biblioteca de solicitações do rastreador Python (com maiúsculas e minúsculas)

1. Introdução à biblioteca de solicitações

Requests é uma biblioteca HTTP simples e elegante projetada para humanos. A biblioteca request é uma biblioteca HTTP nativa, que é mais fácil de usar do que a biblioteca urllib3. A biblioteca de solicitações envia solicitações HTTP 1.1 nativas sem adicionar manualmente strings de consulta a URLs ou dados POST de codificação de formulário. Comparada com a biblioteca urllib3, a biblioteca request possui funções Keep-alive e pool de conexões HTTP totalmente automáticas. A biblioteca de solicitações contém os seguintes recursos.

❖ 1Keep-Alive e pool de conexão

❖ Nomes de domínio e URLs internacionalizados

❖ Sessões com cookies persistentes

❖ Autenticação SSL baseada em navegador

❖ Decodificação automática de conteúdo

❖ Autenticação básica/resumida

❖ Cookie de chave/valor elegante

❖ Descompressão automática

❖ Corpo da resposta Unicode

❖ Suporte a proxy HTTP(S)

❖ Carregar arquivos em partes

❖ Download de streaming

❖ Conexão expirou

❖ Solicitações em partes

❖ Suporte .netrc

1.1 Instalação de Solicitações

pip install requests

1.2 Uso básico de Solicitações

Listagem de código 1-1: envie uma solicitação get e visualize o resultado retornado

import requests
url = 'http://www.tipdm.com/tipdm/index.html' # 生成get请求
rqg = requests.get(url)
# 查看结果类型
print('查看结果类型:', type(rqg))
# 查看状态码
print('状态码:',rqg.status_code)
# 查看编码
print('编码 :',rqg.encoding)
# 查看响应头
print('响应头:',rqg.headers)
# 打印查看网页内容
print('查看网页内容:',rqg.text)
查看结果类型:<class ’requests.models.Response’>
状态码:200
编码 :ISO-8859-1
响应头:{’Date’: ’Mon, 18 Nov 2019 04:45:49 GMT’, ’Server’: ’Apache-Coyote/1.1’, ’
Accept-Ranges’: ’bytes’, ’ETag’: ’W/"15693-1562553126764"’, ’Last-Modified’: ’
Mon, 08 Jul 2019 02:32:06 GMT’, ’Content-Type’: ’text/html’, ’Content-Length’: ’
15693’, ’Keep-Alive’: ’timeout=5, max=100’, ’Connection’: ’Keep-Alive’}

1.3 Solicitar método básico de solicitação

Você pode enviar todas as solicitações http por meio da biblioteca de solicitações:

requests.get("http://httpbin.org/get") #GET请求
requests.post("http://httpbin.org/post") #POST请求
requests.put("http://httpbin.org/put") #PUT请求
requests.delete("http://httpbin.org/delete") #DELETE请求
requests.head("http://httpbin.org/get") #HEAD请求
requests.options("http://httpbin.org/get") #OPTIONS请求

2. Use Request para enviar a solicitação GET

Uma das solicitações mais comuns em HTTP é a solicitação GET. Vamos examinar mais de perto como usar solicitações para construir uma solicitação GET.

Descrição do parâmetro GET: get(url, params=None, **kwargs):

❖ URL: URL a ser solicitada

❖ params : (opcional) dicionário, lista de tuplas ou bytes enviados para a query string da requisição

❖ **kwargs: argumentos de palavra-chave de comprimento variável

Primeiro, crie a solicitação GET mais simples, o link da solicitação é http://httpbin.org/get, o site julgará que, se o cliente iniciar uma solicitação GET, ele retornará as informações da solicitação correspondente, da seguinte maneira é usar requisições para construir uma requisição GET

import requests
r = requests.get(http://httpbin.org/get)
print(r.text)
{
"args": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.24.0",
"X-Amzn-Trace-Id": "Root=1-5fb5b166-571d31047bda880d1ec6c311"
},
"origin": "36.44.144.134",
"url": "http://httpbin.org/get"
}

Pode-se descobrir que iniciamos com sucesso uma solicitação GET e o resultado retornado contém informações como cabeçalho da solicitação, URL e IP. Portanto, para solicitações GET, se você deseja anexar informações adicionais, como geralmente as adiciona?

2.1 Envie uma solicitação com cabeçalhos

Primeiro, tentamos solicitar as informações da página inicial de Zhihu

import requests
response = requests.get(’https://www.zhihu.com/explore’)
print(f"当前请求的响应状态码为:{response.status_code}")
print(response.text)

O código de status da resposta da solicitação atual é: 400

400 Solicitação inválida


openresty

Aqui descobrimos que o código de status da resposta é 400, indicando que nossa solicitação falhou, porque Zhihu descobriu que somos um rastreador, então precisamos disfarçar o navegador e adicionar as informações UA correspondentes.

import requests
headers = {"user-agent": ’Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit
/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36’}
response = requests.get(’https://www.zhihu.com/explore’, headers=headers)
print(f"当前请求的响应状态码为:{response.status_code}")
# print(response.text)

O código de status da resposta da solicitação atual é: 200

<!doctype html>

.......

Aqui adicionamos as informações dos cabeçalhos, que contêm as informações do campo User-Agent, que são as informações de identificação do navegador. Aparentemente nosso disfarce deu certo! Esse método de se fazer passar por um navegador é uma das medidas anti-crawling mais simples.

Descrição do parâmetro GET: o método de envio da solicitação com o cabeçalho da solicitação

request.get(url, headers=headers)

O parâmetro -headers recebe cabeçalhos de solicitação na forma de um dicionário

-O nome do campo do cabeçalho da solicitação é usado como chave e o valor correspondente ao campo é usado como valor

prática

Solicite a página inicial do Baidu https://www.baidu.com, solicite o carregamento de cabeçalhos e imprima as informações solicitadas do cabeçalho!

desatar

import requests
url = 'https://www.baidu.com'
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit
/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"}
# 在请求头中带上User-Agent,模拟浏览器发送请求
response = requests.get(url, headers=headers)
print(response.content)
# 打印请求头信息
print(response.request.headers)

2.2 Envie uma solicitação com parâmetros

Quando usamos a pesquisa do Baidu, geralmente descobrimos que haverá um '?' no endereço do URL, então o ponto de interrogação é o parâmetro de solicitação, também chamado de string de consulta!

Normalmente, não visitamos apenas páginas da Web básicas, especialmente ao rastrear páginas da Web dinâmicas, precisamos passar parâmetros diferentes para obter conteúdo diferente; GET tem dois métodos para passar parâmetros, você pode adicionar parâmetros diretamente no link ou usar parâmetros para adicionar parâmetros.

2.2.1 Carregar parâmetros na url

Inicie uma solicitação diretamente para o URL com parâmetros

import requests
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit
/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"}
url = ’https://www.baidu.com/s?wd=python’
response = requests.get(url, headers=headers)

2.2.2 Carregar dicionário de parâmetros através de params

1. Crie um dicionário de parâmetros de solicitação

2. Traga o dicionário de parâmetros ao enviar uma solicitação para a interface e defina o dicionário de parâmetros como params

import requests
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit
/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"}
# 这是目标url
# url = ’https://www.baidu.com/s?wd=python’
# 最后有没有问号结果都一样
url = ’https://www.baidu.com/s?’
# 请求参数是一个字典 即wd=python
kw = {’wd’: ’python’}
# 带上请求参数发起请求,获取响应
response = requests.get(url, headers=headers, params=kw)
print(response.content)

A julgar pelos resultados da execução, o link solicitado é construído automaticamente como:

http://httpbin.org/get?key2=value2&key1=value1 。

Além disso, o tipo de retorno da página da Web é na verdade o tipo str, mas é muito especial e está no formato JSON. Portanto, se você deseja analisar diretamente o resultado retornado e obter um formato de dicionário, pode chamar diretamente o método json(). Os exemplos são os seguintes:

import requests
r = requests.get("http://httpbin.org/get")
print( type(r.text))
print(r.json())
print( type(r. json()))

< classe 'estr' >

{ 'args' : {}, 'headers' : { 'Accept' : '*/*' , 'Accept-Encoding' : 'gzip, deflate' , 'Host'

'httpbin.org' , 'User-Agent': 'python-requests/2.24.0' , 'X-Amzn-Trace-Id': '

Root=1-5fb5b3f9-13f7c2192936ec541bf97841' }, 'origem': '36.44.144.134', 'url': '

http://httpbin.org/get' }

<class 'dito' >

Pode-se descobrir que, ao chamar o método json(), a string retornada no formato JSON pode ser convertida em um dicionário. No entanto, deve-se observar que, se o resultado retornado não estiver no formato JSON, ocorrerá um erro de análise e uma exceção json.decoder.JSONDecodeError será lançada.

Conteúdo complementar, a string do dicionário recebida será automaticamente codificada e enviada para a url, conforme abaixo:

import requests
headers = {’User-Agent’: ’Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit
/537.36 (KHTML, like Gecko) Chrome/86.0.4240.193 Safari/537.36’}
wd = ’张三同学’
pn = 1
response = requests.get(’https://www.baidu.com/s’, params={’wd’: wd, ’pn’: pn},
headers=headers)
print(response.url)

# A saída é: https://www.baidu.com/s?wd=%E9%9B%A8%E9%9C%93%E5%90%8

C%E5%AD%A6&pn=1

# Pode-se ver que a url foi codificada automaticamente

O código acima é equivalente ao código a seguir, a conversão de codificação de parâmetros é essencialmente usando urlencode

import requests
from urllib.parse import urlencode
headers = {’User-Agent’: ’Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit
/537.36 (KHTML, like Gecko)
wd = ’张三同学’
encode_res = urlencode({’k’: wd}, encoding=’utf-8’)
keyword = encode_res.split(’=’)[1]
print(keyword)
# 然后拼接成url
url = ’https://www.baidu.com/s?wd=%s&pn=1’ % keyword
response = requests.get(url, headers=headers)
print(response.url)

# A saída é: https://www.baidu.com/s?wd=%E9%9B%A8%E9%9C%93%E5

%90%8C%E5%AD%A6&pn=1

2.3 Rastreie páginas da Web usando solicitações GET

O link de solicitação acima retorna uma string no formato JSON, portanto, se você solicitar uma página da Web normal, com certeza obterá o conteúdo correspondente!

import requests
import re
headers = {"user-agent": ’Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit
/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36’}
response = requests.get(’https://www.zhihu.com/explore’, headers=headers)
result = re.findall("(ExploreSpecialCard-contentTitle|ExploreRoundtableCard
questionTitle).*?>(.*?)</a>", response.text)
print([i[1] for i in result])

[' O que há de delicioso na rua Xi'an Huimin? ' , 'Quais lojas de tesouros valem a pena visitar em Xi'an? ' , 'Quais distritos comerciais em Xi'an carregam sua juventude? ' , 'Que bons hábitos de direção você tem que pode compartilhar? ' , 'Existem dicas de direção que apenas motoristas experientes conhecem? ' , 'Atenção quem tem carro, todos devem dominar esses conhecimentos de direção, pode salvar vidas em momentos críticos' , 'Bem-vindo ao Landing! Aviso de recrutamento de membros de Zhihu', 'Pergunta sobre pouso no planeta: dê a você dez yuans para viajar para o futuro, como você pode ganhar a vida? ' , 'Pergunta de pouso no planeta: Que tipo de "super energia" no universo de Zhihu você mais deseja ter? Como você usaria isso? ' , 'Salmão norueguês, a origem é importante' , 'Quais são os lugares mais atraentes da Noruega? ' , 'Como é viver na Noruega? ' , 'Como você vê a produção em massa da tela flexível AMOLED da BOE? Quais são as perspectivas futuras? ' , 'As telas flexíveis podem revolucionar a indústria de telefonia móvel? ' , 'O que é uma bateria flexível dobrável ultrafina? Terá um impacto significativo na duração da bateria do smartphone? ' , 'Como você pode aprender arte bem e obter notas altas no teste de arte com base zero em arte? ', 'A Academia de Belas Artes de Tsinghua é desprezada?', 'Os estudantes de arte são realmente ruins? ', 'Como uma pessoa deve viver esta vida? ', 'O que uma pessoa deve buscar em sua vida? ', 'Será que os seres humanos vão enlouquecer depois de conhecer a verdade última do mundo?', 'A ansiedade é devido à falta de habilidade? ', 'Que tipo de experiência é a fobia social? ' , 'O ditado "Quando você está ocupado não tem tempo para ficar deprimido" é razoável? ']

Aqui adicionamos as informações dos cabeçalhos, que contêm as informações do campo User-Agent, que são as informações de identificação do navegador. Se isso não for adicionado, Zhihu proibirá o rastreamento.

Capturando dados binários No exemplo acima, estamos capturando uma página Zhihu, que na verdade retorna um documento HTML.

O que devo fazer se quiser capturar fotos, áudio, vídeo e outros arquivos? Arquivos como imagens, áudio e vídeo são essencialmente compostos de códigos binários. Devido ao formato de armazenamento específico e ao método de análise correspondente, podemos ver essas várias multimídia.

Portanto, se você quiser pegá-los, precisará obter o código binário deles. Vamos pegar o ícone do site do GitHub como exemplo:

import requests
response = requests.get("https://github.com/favicon.ico")
with
open(’github.ico’, ’wb’) as f:
f.write(response.content)

As duas propriedades do objeto Response, uma é texto e a outra é conteúdo. A primeira representa texto do tipo string e a última representa dados do tipo bytes. Da mesma forma, arquivos de áudio e vídeo também podem ser obtidos dessa maneira.

2.4 Carregar cookie no parâmetro Headers

Os sites costumam usar o campo Cookie no cabeçalho da solicitação para manter o status de acesso do usuário, para que possamos adicionar Cookie ao parâmetro headers para simular a solicitação de usuários comuns.

2.4.1 Obtenção de Cookies

Para poder obter a página de login através de crawlers, ou para resolver o anti-crawling através de cookies, é necessário utilizar request para processar as requisições relacionadas com cookies:

import requests
url = ’https://www.baidu.com’
req = requests.get(url)
print(req.cookies)
# 响应的cookies
for key, value in req.cookies.items():
print(f"{key} = {value}") 

<RequestsCookieJar[<Cookie BDORZ=27315 for .baidu.com/>]>

BDORZ = 27315

Aqui podemos obter Cookies com sucesso chamando primeiro o atributo cookies e podemos descobrir que é do tipo RequestCookieJar. Em seguida, use o método items() para convertê-lo em uma lista de tuplas, percorra e gere o nome e o valor de cada Cookie e realize o percurso e a análise do Cookie.

2.4.2 Login com Cookies

A vantagem de trazer cookies e sessões: você pode solicitar a página após o login.

Desvantagens de trazer cookies e sessões: um conjunto de cookies e sessões geralmente corresponde à solicitação de um usuário muito rapidamente e o número de solicitações é muito grande, o que é facilmente reconhecido como um rastreador pelo servidor.

Tente não usar cookies quando você não precisar de cookies, mas para acessar a página após o login, devemos enviar uma solicitação com cookies. Podemos usar cookies diretamente para manter o status de login. Vamos usar Zhihu como exemplo para ilustrar . Primeiro faça login no Zhihu e copie o conteúdo do Cookie em Cabeçalhos.

➢ Copie User-Agent e Cookie do navegador

➢ O campo e o valor do cabeçalho da solicitação no navegador devem ser consistentes com o parâmetro headers

➢ O valor correspondente à chave Cookie no dicionário de parâmetros de solicitação de cabeçalhos é uma string

import requests
import re
# 构造请求头字典
headers = {
# 从浏览器中复制过来的User-Agent
"user-agent": ’Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (
KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36’,
# 从浏览器中复制过来的Cookie
"cookie": ’xxx这里是复制过来的cookie字符串’}
# 请求头参数字典中携带cookie字符串
response = requests.get(’https://www.zhihu.com/creator’, headers=headers)
data = re.findall(’CreatorHomeAnalyticsDataItem-title.*?>(.*?)</div>’,response.text)
print(response.status_code)
print(data)

Quando fazemos um pedido sem cookies:

import requests
import re
headers = {"user-agent": ’Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit
/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36’}
response = requests.get(’https://www.zhihu.com/creator’, headers=headers)
data = re.findall(’CreatorHomeAnalyticsDataItem-title.*?>(.*?)</div>’,response.text)
print(response.status_code)
print(data)

200

[]

Ele está vazio na saída impressa e, comparado com os dois, o parâmetro headers é usado com sucesso para carregar o cookie para obter a página que só pode ser acessada após o login!

2.4.3 Parâmetros de uso de cookies

Na seção anterior, carregamos cookies no parâmetro headers ou podemos usar parâmetros especiais de cookies.

❖ 1. Parâmetro do formato dos cookies: dicionário

cookies = "cookie 的 name":"cookie 的 value"

➢ O dicionário corresponde à string Cookie no cabeçalho da solicitação, e cada par de pares chave-valor do dicionário é separado por um ponto e vírgula e um espaço

➢ O lado esquerdo do sinal de igual é o nome de um cookie, que corresponde à chave do dicionário de cookies

➢ O lado direito do sinal de igual corresponde ao valor do dicionário de cookies

❖ 2. Como usar os parâmetros dos cookies

resposta = request.get(url, cookies)

❖ 3. Converta a string do cookie no dicionário necessário para o parâmetro cookies:

cookies_dict = { cookie. split('=')[0]: cookie. split('=') [- 1] para cookie em

cookies_str . dividir ( '; ' ) }

❖ 4. Nota: Os cookies geralmente têm um tempo de expiração e, uma vez expirados, precisam ser obtidos novamente

response = requests.get(url, cookies)
import requests
import re
url = ’https://www.zhihu.com/creator’
cookies_str = ’复制的cookies’
headers = {"user-agent": ’Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit
/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36’}
cookies_dict = {cookie.split(’=’, 1)[0]:cookie.split(’=’, 1)[-1] for cookie in
cookies_str.split(’; ’)}
# 请求头参数字典中携带cookie字符串
resp = requests.get(url, headers=headers, cookies=cookies_dict)
data = re.findall(’CreatorHomeAnalyticsDataItem-title.*?>(.*?)</div>’,resp.text)
print(resp.status_code)
print(data)

200

[ 'Em python, como escrever este método com ids diferentes, mas a mesma classe como uma integração? ' , 'Meus pais não têm dinheiro para comprar um computador para mim, o que devo fazer? ' , 'Descreva suas condições de vida atuais em uma frase? ']

2.4.4 Construir o objeto RequestsCookieJar para definir cookies

Aqui também podemos definir cookies construindo o objeto RequestsCookieJar, o exemplo de código é o seguinte:

import requests
import re
url = ’https://www.zhihu.com/creator’
cookies_str = ’复制的cookies’
headers = {"user-agent": ’Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit
/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36’}
jar = requests.cookies.RequestsCookieJar()
for cookie in cookies_str.split(’;’):
key,value = cookie.split(’=’,1)
jar. set(key,value)
# 请求头参数字典中携带cookie字符串
resp = requests.get(url, headers=headers, cookies=jar)
data = re.findall(’CreatorHomeAnalyticsDataItem-title.*?>(.*?)</div>’,resp.text)
print(resp.status_code)
print(data)

200

[ 'Em python, como escrever este método com ids diferentes, mas a mesma classe como uma integração? ' , 'Meus pais não têm dinheiro para comprar um computador para mim, o que devo fazer? ' , 'Descreva suas condições de vida atuais em uma frase? ']

Aqui, primeiro criamos um novo objeto RequestCookieJar, depois usamos o método split() para dividir os cookies copiados, depois usamos o método set() para definir a chave e o valor de cada cookie e, em seguida, chamamos o método get() de solicitações e pass Apenas dê parâmetros aos cookies.

Obviamente, devido às próprias limitações de Zhihu, o parâmetro headers também é indispensável, mas não há necessidade de definir o campo cookie no parâmetro headers original. Após o teste, descobri que também posso fazer login no Zhihu normalmente.

2.4.5 Método de conversão do objeto cookieJar em dicionário de cookies

O objeto resposta obtido pelas requisições possui o atributo cookies. O valor do atributo é um tipo cookieJar, que contém o cookie local definido pelo outro servidor. Como convertemos isso em um dicionário de cookies?

❖ 1. Método de conversão

cookies_dict = requests.utils.dict_from_cookiejar(response.cookies)

❖ 2. O objeto retornado por response.cookies é do tipo cookieJar

❖ 3. A função requests.utils.dict_from_cookiejar retorna o dicionário de cookies

import requests
import re
url = 'https://www.zhihu.com/creator'
cookies_str = '复制的cookies'
headers = {"user-agent": 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit
/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'}
cookie_dict = {cookie.split('=', 1)[0]:cookie.split('=', 1)[-1] for cookie in
cookies_str.split('; ')}
# 请求头参数字典中携带cookie字符串
resp = requests.get(url, headers=headers, cookies=cookies_dict)
data = re.findall('CreatorHomeAnalyticsDataItem-title.*?>(.*?)</div>',resp.text)
print(resp.status_code)
print(data)
# 可以把一个字典转化为一个requests.cookies.RequestsCookieJar对象
cookiejar = requests.utils.cookiejar_from_dict(cookie_dict, cookiejar=None,
overwrite=True)
type(cookiejar) # requests.cookies.RequestsCookieJar
type(resp.cookies) # requests.cookies.RequestsCookieJar
#构造RequestsCookieJar对象进行cookies设置其中jar的类型也是 requests.cookies.
RequestsCookieJar
#cookiejar转字典
requests.utils.dict_from_cookiejar(cookiejar)

2.5 Configurações de tempo limite

No processo de navegação na Internet, muitas vezes encontramos flutuações de rede.No momento, uma solicitação que está esperando há muito tempo ainda pode não ter resultado.

No crawler, se uma requisição não tiver resultado por muito tempo, a eficiência de todo o projeto ficará muito baixa. Nesse momento, precisamos fazer valer a requisição para que ele retorne o resultado em um tempo determinado, caso contrário um erro será relatado.

❖ 1. Como usar o parâmetro timeout timeout

resposta = request.get(url, timeout=3)

❖ 2. timeout=3 significa: após enviar a solicitação, a resposta será retornada em 3 segundos, caso contrário, uma exceção será lançada

url = 'http://www.tipdm.com/tipdm/index.html'

#Defina o tempo limite para 2

print('tempo limite é 2:', requests.get(url,timeout=2))

Se o tempo limite for muito curto, um erro será relatado

request.get(url,timeout = 0.1) #O tempo da nota é 0.001

O tempo limite é 2: <Resposta [200]>

3. Use a solicitação para enviar a solicitação POST

Pensando: Onde usamos requisições POST?

1. Login e registro (na visão dos engenheiros da web, POST é mais seguro que GET, e a senha da conta do usuário e outras informações não serão expostas no endereço url)

2. Quando o conteúdo de texto grande precisa ser transmitido (solicitações POST não requerem comprimento de dados)

Então, da mesma forma, nosso crawler também precisa voltar para simular o navegador para enviar uma requisição post nestes dois locais. Na verdade, enviar uma requisição POST é muito parecido com um método GET, mas precisamos definir os parâmetros em os dados:

Descrição dos parâmetros do POST:

post(url, data=Nenhum, json=Nenhum, **kwargs):

❖ URL: URL a ser solicitada

❖ data : (opcional) dicionário, lista de tuplas, bytes ou objeto tipo arquivo para enviar no corpo da Requisição

❖ json: (opcional) dados JSON, enviados para o corpo da classe Request.

❖ **kwargs: argumentos de palavra-chave de comprimento variável

import requests
payload = {’key1’: ’value1’, ’key2’: ’value2’}
req = requests.post("http://httpbin.org/post", data=payload)
print(req.text)

3.1 POST envia dados JSON

Muitas vezes, os dados que você deseja enviar não são codificados como um formulário e verifica-se que esse problema ocorre especialmente ao rastrear muitos URLs java. Se você passar uma string ao invés de um dict, os dados serão postados diretamente. Podemos usar json.dumps() para converter o dict para o formato str, aqui, além de codificar o dict você mesmo, você também pode usar parâmetros json para passar diretamente, e então ele será codificado automaticamente.

import json
import requests
url = ’http://httpbin.org/post’
payload = {’some’: ’data’}
req1 = requests.post(url, data=json.dumps(payload))
req2 = requests.post(url, json=payload)
print(req1.text)
print(req2.text)

Pode-se verificar que obtivemos com sucesso o resultado retornado, em que a parte do formulário são os dados enviados, o que prova que a solicitação POST foi enviada com sucesso.

notas

O módulo de solicitações envia solicitações com dados, json e params, três métodos de transporte de parâmetros.

params são usados ​​em solicitações get, data e json são usados ​​em solicitações post.

Os parâmetros que os dados podem receber são: dicionário, string, byte, objeto de arquivo.

❖ Use parâmetros json, não importa se a mensagem é do tipo str ou dict, se você não especificar o tipo de conteúdo nos cabeçalhos

Type, o padrão é: application/json.

❖ Use o parâmetro data, a mensagem é um tipo dict, se você não especificar o tipo de conteúdo nos cabeçalhos, o padrão application/x

www-form-urlencoded, que é equivalente ao formulário enviado por formulário comum, converterá os dados do formulário em pares chave-valor.Neste momento, os dados podem ser obtidos de request.POST e do conteúdo de request. body é a=1&b= 2 neste formulário de par chave-valor.

❖ Use o parâmetro data, a mensagem é do tipo str, se você não especificar o tipo de conteúdo nos cabeçalhos, o padrão é application/json.

Ao enviar dados com o parâmetro data, o conteúdo de request.body está no formato a=1&b=2,

Ao enviar dados com parâmetros json, o conteúdo de request.body está na forma de '"a": 1, "b": 2'

3.2 arquivo de upload POST

Se quisermos usar o rastreador para fazer upload de arquivos, podemos usar o parâmetro fifile:

url = 'http://httpbin.org/post'
files = {'file': open('test.xlsx', 'rb')}
req = requests.post(url, files=files)
req.text

Se você tiver um parceiro familiarizado com o desenvolvimento WEB, saiba que, se enviar um arquivo muito grande como uma solicitação de dados de formulário/partes múltiplas, convém transformar a solicitação em um fluxo de dados. Por padrão, as solicitações não são suportadas, você pode usar a biblioteca tripartida request-toolbelt.

3.3 Rastrear páginas da Web usando solicitações POST

Principalmente para encontrar a página da Web a ser analisada

import requests
# 准备翻译的数据
kw =
input("请输入要翻译的词语:")
ps = {"kw": kw}
# 准备伪造请求
headers = {
# User-Agent:首字母大写,表示请求的身份信息;一般直接使用浏览器的身份信息,伪造
爬虫请求
# 让浏览器认为这个请求是由浏览器发起的[隐藏爬虫的信息]
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (
KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36 Edg/85.0.564.41"
}
# 发送POST请求,附带要翻译的表单数据--以字典的方式进行传递
response = requests.post("https://fanyi.baidu.com/sug", data=ps)
# 打印返回的数据
# print(response.content)
print(response.content.decode("unicode_escape"))

4.Solicitações avançadas (1)*Manutenção da sessão da sessão

Esta parte apresenta principalmente a manutenção da sessão e o uso do proxy IP.

Nas requisições, se você usar diretamente métodos como get() ou post(), você pode sim simular requisições de páginas web, mas isso na verdade equivale a uma sessão diferente, ou seja, você usa dois navegadores para abrir páginas diferentes.

Imagine tal cenário, a primeira solicitação usa o método post () para fazer login em um determinado site e, na segunda vez que você deseja obter suas informações pessoais após o login bem-sucedido, usa o método get () para solicitar a página de informações pessoais de novo. Na verdade, isso equivale a abrir dois navegadores. São duas sessões completamente não relacionadas. As informações pessoais podem ser obtidas com sucesso? Claro que não.

 

Alguns amigos podem ter dito, não deveria ser suficiente para mim definir os mesmos cookies em duas solicitações? Sim, mas é complicado fazer isso e temos uma solução mais fácil.

Na verdade, a principal maneira de resolver esse problema é manter a mesma sessão, o que equivale a abrir uma nova guia do navegador em vez de abrir um novo navegador. Mas não quero definir cookies sempre, então o que devo fazer? Neste momento, surge uma nova arma, o objeto Session.

Ao usá-lo, podemos facilmente manter uma sessão e não precisamos nos preocupar com cookies, ele cuidará disso automaticamente para nós.

A classe Session no módulo de requisições pode processar automaticamente os cookies gerados durante o processo de envio de requisições e obtenção de respostas, de forma a atingir o propósito de preservação do estado. Em seguida, passamos a aprendê-lo.

4.1 A função e os cenários de aplicação de requests.session

❖ A função de request.session

Manipular cookies automaticamente, ou seja, a próxima requisição trará o cookie anterior

❖ Cenários de aplicação de request.session

Lidar automaticamente com os cookies gerados durante várias solicitações consecutivas

4.2 Como usar request.session

Depois que a instância da sessão solicitar um site, o cookie local definido pelo outro servidor será salvo na sessão e, na próxima vez que a sessão for usada para solicitar o outro servidor, o cookie anterior será trazido.

session = request .session () # instanciar objeto de sessão

resposta = sessão. get ( url , cabeçalhos , ...)

resposta = sessão. postar ( url , dados , ...)

Os parâmetros da solicitação get ou post enviada pelo objeto de sessão são exatamente os mesmos enviados pelo módulo de solicitações.

4.3 Use a sessão para manter as informações de login do github

❖ Capture todo o processo de login do github e acesso a páginas que só podem ser acessadas após o login

❖ Determine o endereço url, o método de solicitação e os parâmetros de solicitação necessários da solicitação de login

-Alguns parâmetros de requisição estão no conteúdo da resposta correspondente a outras urls, que podem ser obtidas usando o módulo re

❖ Determine o endereço url e o método de solicitação da página que só pode ser acessada após o login

❖ Conclusão de código usando request.session

import requests
import re
# 构造请求头字典
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (
KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36',}
# 实例化session对象
session = requests.session()
# 访问登陆页获取登陆请求所需参数
response = session.get(https://github.com/login, headers=headers)
authenticity_token = re.search('name="authenticity_token" value="(.*?)" />',
response.text).group(1) # 使用正则获取登陆请求所需参数
# 构造登陆请求参数字典
data = {
'commit': 'Sign in', # 固定值
'utf8': ' ', # 固定值
'authenticity_token': authenticity_token, # 该参数在登陆页的响应内容中
'login':
input('输入github账号:'),
'password':
input('输入github账号:')}
# 发送登陆请求(无需关注本次请求的响应)
session.post(https://github.com/session, headers=headers, data=data)
# 打印需要登陆后才能访问的页面
response = session.get(https://github.com/settings/profile, headers=headers)
print(response.text)

Você pode usar a ferramenta de comparação de texto para revisão!

5.Solicitações avançadas (2)*Uso de proxy

Para alguns sites, o conteúdo pode ser obtido normalmente após diversas solicitações durante o teste. Mas uma vez iniciado o rastreamento em grande escala, para solicitações frequentes e em grande escala, o site pode exibir um código de verificação ou pular para a página de autenticação de login ou até mesmo bloquear diretamente o IP do cliente, resultando em inacessibilidade por um determinado período de tempo .

Bem, para evitar que isso aconteça, precisamos configurar um proxy para resolver esse problema, o que requer o uso do parâmetro proxies. Pode ser definido desta forma:

O parâmetro proxy proxy especifica o ip do proxy, para que o ip do proxy correspondente encaminhe a solicitação que enviamos para o servidor proxy, então vamos primeiro entender o ip do proxy e o servidor proxy.

5.1 O processo de utilização do agente

1. Proxy ip é um ip apontando para um servidor proxy

2. O servidor proxy pode nos ajudar a encaminhar a solicitação ao servidor de destino

5.2 Proxy de encaminhamento e proxy reverso

Conforme mencionado anteriormente, o IP do proxy especificado pelo parâmetro proxy aponta para o servidor proxy de encaminhamento, portanto, há um servidor reverso correspondente; agora vamos entender a diferença entre o servidor proxy de encaminhamento e o servidor proxy reverso.

❖ Distinguir entre proxy direto ou reverso do ponto de vista da parte que envia a solicitação

❖ Encaminhar a solicitação para o navegador ou para o cliente (a parte que envia a solicitação) é chamado de proxy de encaminhamento

- o navegador conhece o endereço IP real do servidor que lida com a solicitação, como uma VPN

❖ Não encaminha a solicitação para o navegador ou para o cliente (a parte que envia a solicitação), mas encaminha a solicitação para o servidor que finalmente processa a solicitação, o que é chamado de proxy reverso

- O navegador não conhece o endereço real do servidor, como nginx.

5.3 Classificação do proxy ip (servidor proxy)

❖ De acordo com o grau de anonimato do proxy IP, o proxy IP pode ser dividido nas três categorias a seguir:

➢ Proxy Transparente: Embora o proxy transparente possa "ocultar" diretamente seu endereço IP, você ainda pode descobrir quem você é.

Os cabeçalhos de solicitação recebidos pelo servidor de destino são os seguintes:

REMOTE_ADDR = IP do proxy

HTTP_VIA = IP do proxy

HTTP_X_FORWARDED_FOR = Seu IP

➢ Proxy Anônimo (Anonymous Proxy): Com o proxy anônimo, outras pessoas só podem saber que você usa um proxy, mas não podem saber quem você é.

Os cabeçalhos de solicitação recebidos pelo servidor de destino são os seguintes:

REMOTE_ADDR = IP proxy

HTTP_VIA = IP proxy

HTTP_X_FORWARDED_FOR = IP proxy

➢ Proxy de alto anonimato (proxy Elite ou Proxy de alto anonimato): O Proxy de alto anonimato torna impossível que outras pessoas descubram que você está usando um proxy, por isso é a melhor escolha. ** Não há dúvida de que usar um proxy de alto perfil funciona melhor **.

Os cabeçalhos de solicitação recebidos pelo servidor de destino são os seguintes:

REMOTE_ADDR = IP do proxy

HTTP_VIA = não determinado

HTTP_X_FORWARDED_FOR = não determinado

❖ Dependendo do protocolo utilizado pelo site, é necessário um serviço de proxy do protocolo correspondente.

Os protocolos usados ​​para atender solicitações de proxies podem ser categorizados como:

➢ Proxy http: URL de destino é o protocolo http

➢ https proxy: o URL de destino é o protocolo https

➢ proxy de túnel de meias (como proxy de meias5), etc.:

✾ 1. O proxy de meias simplesmente transmite pacotes de dados, independente do protocolo de aplicação (FTP, HTTP, HTTPS, etc.).

✾ 2. O proxy de meias leva menos tempo do que os proxies http e https.

✾ 3. O proxy de meias pode encaminhar solicitações http e https

5.4 Uso de parâmetros de proxy de proxies

Para fazer com que o servidor pense que não é o mesmo cliente que está solicitando; para evitar que solicitações frequentes a um nome de domínio sejam bloqueadas, precisamos usar proxy ip; então aprenderemos o uso básico de como as solicitações módulo usa proxy ip.

response = requests . get ( url , proxies = proxies )
proxies 的形式:字典
proxies = {
" http ": " http :// 12.34.56.79: 9527 ",
" https ": " https :// 12.34.56.79: 9527 ",
}

Nota: Se o dicionário de proxies contiver vários pares chave-valor, o ip do proxy correspondente será selecionado de acordo com o protocolo do endereço url ao enviar a solicitação

import requests
proxies = {
"http": "http://124.236.111.11:80",
"https": "https:183.220.145.3:8080"}
req = requests.get(’http://www.baidu.com’,proxies =proxies)
req.status_code

6. Solicita verificação de certificado SSL avançada (3)*

Além disso, as solicitações também fornecem a função de verificação de certificado. Ao enviar uma solicitação HTTP, ele verificará o certificado SSL, podemos usar o parâmetro Verify para controlar se deve verificar este certificado. Na verdade, se o parâmetro de verificação não for adicionado, o padrão é True e será verificado na dinâmica.

Agora vamos testar com as requisições:

import requests
url = 'https://cas.xijing.edu.cn/xjtyrz/login'
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit
/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'}
req = requests.get(url,headers=headers)

SSLError: HTTPSConnectionPool(host= 'cas.xijing.edu.cn' , port=443): Máximo de tentativas

excedido com url: /xjtyrz/login (causado por SSLError(SSLCertVerificationError(1,

'Falha na verificação do certificado [SSL: CERTIFICATE_VERIFY_FAILED]: não foi possível obter

certificado de emissor local (_ssl.c:1123)' )))

Um erro SSL Error é solicitado aqui, indicando que o erro de verificação do certificado. Portanto, se um site HTTPS for solicitado, mas o certificado verificar a página errada, esse erro será relatado, então como evitar esse erro? Muito simples, defina o parâmetro de verificação como Falso.

O código correspondente é o seguinte:

import requests
url = 'https://www.jci.edu.cn/'
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit
/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'}
req = requests.get(url,headers=headers,verify=False)
req.status_code

200

Não consigo encontrar nenhuma página da web que exija verificação SSL, que raiva!

No entanto, descobrimos que um aviso foi relatado e sugeriu que atribuíssemos um certificado a ele. Podemos bloquear este aviso definindo ignorar avisos:

import requests
from requests.packages import urllib3
urllib3.disable_warnings()
url = 'https://www.jci.edu.cn/'
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit
/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'}
req = requests.get(url,headers=headers,verify=False)
req.status_code

200

Ou ignore os avisos capturando-os no log:

import logging
import requests
logging.captureWarnings(True)
url = 'https://www.jci.edu.cn/'
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit
/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'}
req = requests.get(url,headers=headers,verify=False)
req.status_code

200

Claro, também podemos especificar um certificado local para ser usado como certificado do cliente, pode ser um único arquivo (contendo chave e certificado) ou uma tupla contendo dois caminhos de arquivo:

import requests
response = requests.get(https://www.12306.cn’,cert=(’./path/server.crt’,’/path/key
))
print(response.status_code)

200

Obviamente, o código acima é um exemplo de demonstração, precisamos ter os arquivos crt e key e especificar seus caminhos. Observe que a chave do certificado privado local deve estar no estado descriptografado e a chave no estado criptografado não é suportada. Existem muito poucos URLs como este agora!

7. Outros conteúdos da biblioteca de Pedidos

7.1 Visualizar o conteúdo da resposta

Após o envio da solicitação, a resposta é obtida naturalmente. No exemplo acima, usamos text e content para obter o conteúdo da resposta. Além disso, existem muitas propriedades e métodos que podem ser usados ​​para obter outras informações, como códigos de status, cabeçalhos de resposta, cookies, etc.

Os exemplos são os seguintes:

import requests
url = 'https://www.baidu.com'
req = requests.get(url)
print(req.status_code)
# 响应状态码
print(req.text)
# 响应的文本内容
print(req.content)
# 响应的二进制内容
print(req.cookies)
# 响应的cookies
print(req.encoding)
# 响应的编码
print(req.headers)
# 响应的头部信息
print(req.url)
# 响应的网址
print(req.history)
# 响应的历史

7.2 Exibir código de status e codificação

Use o formato rqg.status_code para visualizar o código de status retornado pelo servidor e use o formato rqg.encoding para codificar a página da Web por meio das informações do cabeçalho HTTP retornadas pelo servidor. Deve-se observar que, quando a biblioteca Requests adivinhar errado, você precisará especificar manualmente o código de codificação para evitar caracteres ilegíveis no conteúdo da página da web retornado.

7.3 Envie uma solicitação get e especifique manualmente a codificação

Código 1-2: envie uma solicitação get e especifique manualmente a codificação

url = 'http://www.tipdm.com/tipdm/index.html'
rqg = requests.get(url)
print('状态码 ',rqg.status_code)
print('编码 ',rqg.encoding)
rqg.encoding = 'utf-8' #手动指定编码
print('修改后的编码 ',rqg.encoding)
# print(rqg.text)

código de status

200

codificação

ISO-8859-1

codificação modificada

utf-8

notas

O método de especificação manual não é flexível e não pode se adaptar a diferentes codificações de páginas da Web no processo de rastreamento, mas o método de uso da biblioteca chardet é relativamente simples e flexível. A biblioteca chardet é um módulo de detecção de codificação de string/arquivo muito bom

7.4 Uso da biblioteca chardet

O método detect da biblioteca chartdet pode detectar a codificação de uma determinada string e sua sintaxe é a seguinte.

chartdet.detect(byte_str)

Parâmetros e descrições comuns do método de detecção

byte_str: recebe string. Uma string que representa a codificação a ser detectada. nenhum padrão

7.5 Use o método de detecção para detectar a codificação e especificar

Código 1-3: Use o método de detecção para detectar a codificação e especificar a codificação

import chardet
url = 'http://www.tipdm.com/tipdm/index.html'
rqg = requests.get(url)
print(rqg.encoding)
print(chardet.detect(rqg.content))
rqg.encoding = chardet.detect(rqg.content)['encoding']
# 访问字典元素
print(rqg.encoding)

ISO-8859-1

{ 'codificação': 'utf-8', 'confiança': 0,99, 'idioma': ''}

utf-8

7.6 Teste Abrangente da Biblioteca de Solicitações

Envie uma solicitação GET completa para o site 'http://www.tipdm.com/tipdm/index.html', que inclui link, cabeçalho de solicitação, cabeçalho de resposta, tempo limite e código de status, e a codificação está definida corretamente.

Listagem 1-6: Gere uma solicitação HTTP completa.

# 导入相关的库
import requests
import chardet
# 设置url
url = 'http://www.tipdm.com/tipdm/index.html'
# 设置请求头
headers = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit
/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36"}
# 生成GET请求,并设置延时为2
rqg = requests.get(url,headers=headers,timeout = 2)
# 查看状态码
print("状态码 ",rqg.status_code)
# 检测编码(查看编码)
print('编码 ',rqg.encoding)
# 使用chardet库的detect方法修正编码
rqg.encoding = chardet.detect(rqg.content)['encoding']
# 检测修正后的编码
print('修正后的编码: ',rqg.encoding)
#查看响应头
print('响应头:',rqg.headers)
# 查看网页内容
#print(rqg.text)

código de status

200

codificação

ISO-8859-1

Codificação corrigida: utf-8

Cabeçalho da resposta: { 'Data': 'Seg, 18 de novembro de 2019 06:28:56 GMT', 'Servidor': 'Apache-Coyote/1.1', '

Accept-Ranges': 'bytes', 'ETag': 'W/"15693-1562553126764"', 'Última modificação': '

Seg, 08 de julho de 2019 02:32:06 GMT' , 'Tipo de conteúdo' : 'text/html' , 'Comprimento do conteúdo' : '

15693' , 'Keep-Alive' : 'timeout=5, max=100' , 'Connection' : 'Keep-Alive' }

Acho que você gosta

Origin blog.csdn.net/y1282037271/article/details/129169619
Recomendado
Clasificación