Python >> Tutoriel Python >  >> Python Tag >> Requests

Impossible d'obtenir un certain élément d'une page Web à l'aide de requêtes

Vous devez décoder l'e-mail.

import requests
from bs4 import BeautifulSoup

def cfDecodeEmail(encodedString):
    r = int(encodedString[:2],16)
    email = ''.join([chr(int(encodedString[i:i+2], 16) ^ r) for i in range(2, len(encodedString), 2)])
    return email

url = "https://www.seafoodsource.com/supplier-directory/Tri-Cor-Flexible-Packaging-Inc"

res = requests.get(url,headers={"User-Agent":"Mozilla/5.0"})
soup = BeautifulSoup(res.text,'lxml')
name = soup.select_one("[class$='-supplier-view-main-container'] > h1").text
email = cfDecodeEmail(soup.select_one("[class='__cf_email__']").get("data-cfemail"))
print(f'{"Name: "}{name}\n{"Email: "}{email}')

Sortie :

Name: Tri-Cor Flexible Packaging Inc
Email: [email protected]

La réponse courte est que vous devez décoder la chaîne de l'e-mail, car elle est masquée.

Vous trouverez ci-dessous la raison pour laquelle vous devez décoder la chaîne d'e-mail que vous avez obtenue de la source de fruits de mer.

Le site Web seascapesource.com utilise Cloudflare, qui est une société américaine qui fournit à ses clients la sécurité du site Web, l'atténuation des attaques DDoS et d'autres services.

J'ai déterminé que le site utilisait Cloudflare en envoyant un ping à seasource.com, qui a renvoyé l'adresse IP 104.24.19.99. Selon ARIN (American Registry for Internet Numbers), cette adresse IP appartient au netblock 104.16.0.0 - 104.31.255.255, qui est enregistré auprès de Cloudflare.

La chaîne cf_email dans votre soupe indique également que l'adresse e-mail est protégée par Cloudflare (CF). Une autre indication est ce message d'avertissement, qui s'affiche lorsque vous cliquez sur le lien protégé lors de l'affichage de la source de la page.

Cloudflare Email Address Obfuscation contribue à la prévention du spam en masquant les adresses e-mail qui apparaissent sur le site Web cible aux collecteurs d'e-mails et autres bots, mais l'e-mail est visible pour les visiteurs normaux du site.

Sous cette protection, une adresse e-mail devient une série d'octets codés en hexadécimal de longueur variable, en fonction de la longueur de l'adresse e-mail.

Il convient de noter que cette méthode de codage n'est pas conçue pour crypter en toute sécurité une adresse e-mail, car elle est cryptographiquement faible, mais elle est seulement conçu pour confondre les grattoirs Web non intelligents qui recherchent des liens mailto:dans le code HTML. En d'autres termes, cette méthode d'encodage est utilisée pour obscurcir une adresse e-mail, mais pas pour assurer complètement sa confidentialité.

L'adresse e-mail encodée dans votre question est :

aeccdcd7cfc0eedadcc783cdc1dc80cdc1c3

Le premier octet de cette adresse e-mail est ae ou hexadécimal 0xae. Cet octet est une clé utilisée pour chiffrer et déchiffrer les octets restants en effectuant un XOR au niveau du bit de la clé avec chaque octet suivant.

Par exemple :

0xae ^ 0xcc est hexadécimal 62, qui se traduit par b en ASCII

0xae ^ 0xdc est hexadécimal 72, qui se traduit par r en ASCII

0xae ^ 0xd7 est hexadécimal 79, qui se traduit par y en ASCII

0xae ^ 0xcf est hexadécimal 61, qui se traduit par a en ASCII

0xae ^ 0xc0 est 6e hexadécimal, qui se traduit par n en ASCII

Cela s'écrit bryan , qui est la première partie de l'adresse e-mail décodée.

Le bitwise XORing se produit dans ce code :

chr(int(chaîne_encodée[i:i+2], 16) ^ base_16)

Laissez-moi vous expliquer davantage :

Le premier octet de la chaîne de codage est la clé de chiffrement, qui dans ce cas est ae ou 0xae.

Si nous convertissons 0xae en décimal, cela devient 174.

Lorsque nous convertissons l'octet suivant 0xcc en décimal, il devient 204.

Convertissons ces décimales en utilisant l'opérateur binaire ^.

^ XOR exclusif au niveau du bit

Renvoie le résultat du XOR au niveau du bit de deux entiers.

first_byte = 174 # ae
second_byte = 204 # cc
xor_decimal = first_byte ^ second_byte 
print (xor_decimal) 
# outputs 
98

Convertissons ces décimales en hexadécimales (base 16). Nous pouvons utiliser la fonction intégrée "hex" en Python pour y parvenir.

first_byte = 174 # ae
second_byte = 204 # cc
xor_decimal = first_byte ^ second_byte 
print (hex)xor_decimal)
# outputs 
62

Comme je l'ai mentionné précédemment hexadécimal 62, se traduit par b en ASCII

Regardons l'itération d'octet suivante dans la chaîne encodée.

first_byte = 174 # ae
next_byte = 220 # dc
xor_decimal = first_byte ^ next_byte 
print (hex)xor_decimal)
# outputs 
72

Comme je l'ai mentionné précédemment hexadécimal 72, se traduit par r en ASCII

Je pense qu'il est pertinent de montrer comment convertir une chaîne hexadécimale en décimal.

 # without the 0x prefix
 decimal = int('ae', 16)
 print (decimal)
 # outputs
 174 

 # with the 0x prefix
 decimal = int('0xae', 0)
 print (decimal)
 # outputs
 174 

Conversion de texte ASCII en hexadécimal pour l'adresse e-mail masquée :

Adresse e-mail ASCII :[email protected]

Adresse e-mail hexadécimale :62 72 79 61 6e 40 74 72 69 2d 63 6f 72 2e 63 6f 6d

Nous pouvons utiliser la fonction intégrée bytearray en Python pour décoder cette chaîne hexadécimale :

hex_string = '62 72 79 61 6e 40 74 72 69 2d 63 6f 72 2e 63 6f 6d'
ascii_conversion = bytearray.fromhex(hex_string).decode()
print (ascii_conversion)
# outputs
[email protected]

Conversion de texte ASCII en décimal pour l'adresse e-mail obscurcie :

Adresse e-mail ASCII :[email protected]

Adresse e-mail décimale :98 114 121 97 110 64 116 114 105 45 99 111 114 46 99 111 109

Si nous ajoutons le nombre décimal 174, qui était ae dans la chaîne obscurcie à la tête de l'adresse e-mail décimale :

Adresse e-mail décimale :174 98 114 121 97 110 64 116 114 105 45 99 111 114 46 99 111 109

Adresse e-mail ASCII :®[email protected]

Il semble que ® était le caractère ASCII utilisé comme clé de chiffrement pour la chaîne masquée dans votre question.

Je m'en voudrais de ne pas mentionner les nombres binaires et les opérations XOR.

Conversions au premier octet :

  • numéro hexadécimal :ae
  • nombre décimal :174
  • hexadécimaux (base 16) :98
  • numéro binaire :10101110
  • texte ascii :®

Conversions de deuxième octet :

  • numéro hexadécimal :cc
  • nombre décimal :204
  • hexadécimaux (base 16) :62
  • numéro binaire :11001100
  • texte ascii :b

Nous pouvons effectuer les mêmes opérations ^ Bitwise Exclusive XOR avec les nombres binaires ci-dessus :

# the notation 0b in front of the number is used to express that the value is 
# a binary literal
first_byte_binary = 0b10101110
second_byte_binary = 0b11001100
xor_binary = first_byte_binary ^ second_byte_binary
print (bin(xor_binary))
# outputs
0b1100010

print (xor_binary)
# outputs 
98

print (hex(xor_binary))
# outputs
0x62

ascii_conversion = bytearray.fromhex(hex(xor_binary)[2:]).decode()
print (ascii_conversion)
# outputs
b

Voici comment décoder les adresses e-mail obfusquées par Cloudflare.

import requests
from bs4 import BeautifulSoup

url = "https://www.seafoodsource.com/supplier-directory/Tri-Cor-Flexible-Packaging-Inc"

raw_html = requests.get(url,headers={"User-Agent":"Mozilla/5.0"})
soup = BeautifulSoup(raw_html.text,'lxml')

company_information = []

def get_company_name(soup):
  company_name = soup.find('li', {'class': 'active'}).text
  company_information.append(company_name)
  return

def decode_cloudflare_protected_email(encoded_string):
    # converting the encoding string to int base 16
    base_16 = int(encoded_string[:2], 16)
    decoded_email = ''.join([chr(int(encoded_string[i:i+2], 16) ^ base_16) for i in range(2, len(encoded_string), 2)])
    company_information.append(decoded_email)
    return

get_company_name(soup)

encoded_email = soup.select_one("[class='__cf_email__']").get("data-cfemail")
decode_cloudflare_protected_email(encoded_email)

print (company_information)
# outputs
['Tri-Cor Flexible Packaging Inc', '[email protected]']

Si vous êtes plus intéressé par l'exploration du chiffrement XOR, je vous suggérerais de regarder le xortool, qui est un projet Github d'Aleksei Hellman.