Compartilhamento de tecnologia

【Rastreador】Noções básicas sobre o rastreador

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina


1. Resposta e solicitação HTTP

HTTP é um protocolo cliente-servidor e as duas partes da comunicação são o cliente e o servidor. O cliente envia uma solicitação HTTP e o servidor recebe e processa a solicitação e retorna uma resposta HTTP.

1. Solicitação HTTP

As solicitações HTTP consistem em linhas de solicitação, cabeçalhos de solicitação, linhas em branco e dados de solicitação (como dados de formulário em solicitações POST).

  • A linha de solicitação contém o método de solicitação, o URL solicitado e a versão do protocolo. Os métodos de solicitação comuns incluem GET, POST, PUT, DELETE, etc.
  • O cabeçalho da solicitação contém outras informações sobre o cliente e a solicitação, como User-Agent, Accept, Content-Type, etc.
  • Uma linha em branco é usada para separar os cabeçalhos da solicitação e os dados da solicitação.
  • Os dados de solicitação normalmente são usados ​​para solicitações POST e contêm dados enviados.

Exemplo de solicitação:

POST /api/users HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36
Accept: application/json
Content-Type: application/json
Content-Length: 27

{
  "name": "John",
  "age": 30
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

linha de solicitação:POST /api/usuários HTTP/1.1

Cabeçalho da solicitação: Contém Host, User-Agent, Accept, Content-Type, Content-Length, etc.

linha em branco: Linha em branco entre o cabeçalho e o corpo da solicitação

Solicitar corpo:dados JSON

2. Resposta HTTP

A resposta HTTP consiste em linha de status, cabeçalhos de resposta, linhas em branco e dados de resposta.

  • A linha de status contém a versão do protocolo, o código de status e a mensagem de status. O código de status indica o resultado do processamento da solicitação, como 200 indicando sucesso, 404 indicando recurso não encontrado, 500 indicando erro interno do servidor, etc.
  • O cabeçalho de resposta contém outras informações sobre o servidor e a resposta, como Servidor, Tipo de Conteúdo, Comprimento do Conteúdo, etc.
  • Uma linha em branco é usada para separar cabeçalhos de resposta e dados de resposta.
  • Os dados de resposta contêm dados retornados pelo servidor, como HTML, JSON, etc.

Supondo que o servidor retorne uma página HTML simples, a resposta poderia ser a seguinte:

HTTP/1.1 200 OK
Date: Sun, 02 Jun 2024 10:20:30 GMT
Server: Apache/2.4.41 (Ubuntu)
Content-Type: text/html; charset=UTF-8
Content-Length: 137
Connection: keep-alive

<!DOCTYPE html>
<html>
<head>
    <title>Example Page</title>
</head>
<body>
    <h1>Hello, World!</h1>
    <p>This is a sample HTML page.</p>
</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

linha de status:HTTP/1.1 200 OK

cabeçalho de resposta: contém data, servidor, tipo de conteúdo, comprimento do conteúdo, conexão, etc.

linha em branco: Linha em branco entre os cabeçalhos de resposta e o corpo da resposta

corpo de resposta: Contém código HTML

3. Código de status

Os códigos de status HTTP indicam os resultados do processamento da solicitação pelo servidor. Os códigos de status comuns incluem:

  • 1xx: Resposta informativa, indicando que a solicitação foi recebida e o processamento continua.
  • 2xx: sucesso, indicando que a solicitação foi recebida, compreendida e aceita com sucesso pelo servidor.
  • 3xx: Redirecionar, indicando que ações adicionais são necessárias para concluir a solicitação.
  • 4xx: Erro do cliente, indicando que o servidor não pode processar a solicitação.
  • 5xx: Erro no servidor, indicando que ocorreu um erro enquanto o servidor processava a solicitação.

código de status

2. Solicita biblioteca

A biblioteca Requests do Python é uma biblioteca HTTP muito poderosa e fácil de usar.

Antes de usá-lo, você precisa instalar a biblioteca Requests:pip install requests

1. Inicie uma solicitação GET

A solicitação GET é usada para solicitar dados do servidor. Fazer uma solicitação GET usando a biblioteca Requests é muito simples:

import requests
# 发起GET请求
response = requests.get('https://news.baidu.com')
# 检查响应状态码
if response.status_code == 200:
    # 打印响应内容
    print(response.text)
else:
    print(f"请求失败,状态码:{response.status_code}")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

2. Inicie uma solicitação POST

A solicitação POST é usada para enviar dados ao servidor. Por exemplo, sites que exigem login geralmente usam solicitações POST para enviar um nome de usuário e uma senha. O método de uso da biblioteca Requests para iniciar uma solicitação POST é o seguinte:

import requests

# 定义要发送的数据
data = {
    'username': '123123123',
    'password': '1231231312'
}

# 发起POST请求
response = requests.post('https://passport.bilibili.com/x/passport-login/web/login', data=data)

# 检查响应状态码
if response.status_code == 200:
    # 打印响应内容
    print(response.text)
else:
    print(f"请求失败,状态码:{response.status_code}")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

3. Processar cabeçalhos de solicitação

Em alguns sites (como Douban), o mecanismo anti-rastreamento não é permitido para rastreadores, e os cabeçalhos e parâmetros de solicitação HTTP precisam ser definidos para fingir ser um navegador e passar pela autenticação.

import requests

response = requests.get("https://movie.douban.com/top250")
if response.ok:
    print(response.text)
else:
    print("请求失败:" + str(response.status_code))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

Falha na solicitação

Por exemplo, se o código acima não definir o cabeçalho da solicitação, Douban nos negará o acesso.

imagem-20240607014319894

Podemos entrar no site à vontade, encontrar um User-Agent pronto e colocá-lo em nosso cabeçalho de solicitação.

import requests

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36 Edg/125.0.0.0"
}

response = requests.get("https://movie.douban.com/top250", headers=headers)
print(response.text)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

imagem-20240607014435738

Desta forma, você pode acessar Douban e obter o conteúdo da página web.

3. Biblioteca BeautifulSoup

BeautifulSoup é uma biblioteca Python para análise de documentos HTML e XML, especialmente para extração de dados de páginas da web.

Antes de usar, você precisa instalar a biblioteca BeautifulSoup:pip install beautifulsoup4

1. Analise documentos HTML

html.parser É o analisador integrado do Python e é adequado para a maioria dos cenários. Veja Douban acima como exemplo.

import requests
from bs4 import BeautifulSoup

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36 Edg/125.0.0.0"
}

response = requests.get("https://movie.douban.com/top250", headers=headers)
html = response.text
# 使用html.parser来解析HTML内容
soup = BeautifulSoup(html, "html.parser")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

2. Encontre e extraia dados

BeautifulSoup oferece vários métodos para localizar e extrair dados de documentos HTML.

Métodos comuns do BeautifulSoup:

  • find(tag, attributes): encontre a primeira tag que corresponda aos critérios.
  • find_all(tag, attributes): Encontre todas as tags correspondentes.
  • select(css_selector): use seletores CSS para encontrar tags que correspondam aos critérios.
  • get_text(): Obtenha o conteúdo do texto dentro do rótulo.
  • attrs: Obtenha o dicionário de atributos da tag.

Ⅰ. Encontre um único elemento

find O método é usado para encontrar o primeiro elemento que atende aos critérios. Por exemplo, para encontrar o primeiro título de uma página:

title = soup.find("span", class_="title")
print(title.string)
  • 1
  • 2

Ⅱ Encontre todos os elementos

findAll O método é usado para encontrar todos os elementos que atendem aos critérios. Por exemplo, para localizar todos os títulos de uma página:

all_titles = soup.findAll("span", class_="title")
for title in all_titles:
    print(title.string)
  • 1
  • 2
  • 3

Ⅲ Use o seletor CSS

select O método permite usar seletores CSS para encontrar elementos. Por exemplo, para encontrar todos os títulos:

all_titles = soup.select("span.title")
for title in all_titles:
    print(title.get_text())
  • 1
  • 2
  • 3

IV. Obtenha atributos do elemento

pode usarattrs Propriedades Obtém o dicionário de atributos do elemento. Por exemplo, obtenha os URLs de todas as imagens:

all_images = soup.findAll("img")
for img in all_images:
    print(img['src'])
  • 1
  • 2
  • 3

4. Rastreie a lista de filmes de Douban

imagem-20240607021500369

Título do filme: o nome da tag HTML é: span e o atributo de classe do elemento especificado é título.

imagem-20240607021403243

Classificação: a tag HTML é: span e o atributo de classe do elemento especificado é rating_num

import requests
from bs4 import BeautifulSoup

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36 Edg/125.0.0.0"
}
    response = requests.get(f"https://movie.douban.com/top250", headers=headers)
    html = response.text
    soup = BeautifulSoup(html, "html.parser")

    # 获取所有电影
    all_movies = soup.find_all("div", class_="item")

    for movie in all_movies:
        # 获取电影标题
        titles = movie.find_all("span", class_="title")
        for title in titles:
            title_string = title.get_text()
            if "/" not in title_string:
                movie_title = title_string

        # 获取电影评分
        rating_num = movie.find("span", class_="rating_num").get_text()

        # 输出电影标题和评分
        print(f"电影: {movie_title}, 评分: {rating_num}")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

imagem-20240607021144542

O rastreamento foi bem-sucedido, mas apenas a primeira página foi rastreada e o conteúdo subsequente não foi rastreado com êxito.Analise a conexão da URL acima, cada página passa a URL nostartOs parâmetros são paginados.

imagem-20240607020345475

import requests
from bs4 import BeautifulSoup

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36 Edg/125.0.0.0"
}

for start_num in range(0, 250, 25):
    response = requests.get(f"https://movie.douban.com/top250?start={start_num}", headers=headers)
    html = response.text
    soup = BeautifulSoup(html, "html.parser")

    # 获取所有电影条目
    all_movies = soup.find_all("div", class_="item")

    for movie in all_movies:
        # 获取电影标题
        titles = movie.find_all("span", class_="title")
        for title in titles:
            title_string = title.get_text()
            if "/" not in title_string:
                movie_title = title_string

        # 获取电影评分
        rating_num = movie.find("span", class_="rating_num").get_text()

        # 输出电影标题和评分
        print(f"电影: {movie_title}, 评分: {rating_num}")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28