
Lorsque l'IP d'un proxy s'écrase sur des données JSON, comment jouer sans se retourner ?
Les confrères engagés dans les crawlers comprennent qu'à chaque fois que l'on revient d'Internet pour récupérer des données, neuf fois sur dix il s'agit du format JSON. Cette chose a l'air rafraîchissante, mais elle est plus gênante que la démolition de poupées russes gigognes. En particulier lors de l'utilisation d'un proxy IP pour collecter des données, on rencontre souvent les problèmes suivantsTypes de données confus, erreurs de codage, imbrication trop profondeCes papillons de nuit. La semaine dernière, je suis tombé sur un cas : ipipgo agent résidentiel dynamique pour attraper les données d'une entreprise de commerce électronique, les résultats du retour du champ de prix JSON sera une chaîne de "199 ″, un moment et puis changer le nombre de 199, presque à la base de données pour obtenir effondré.
import json
from requests import Session
configuration du proxy ipipgo (voir ici pour les grandes lignes)
proxy_config = {
"http" : "http://user:pass@gateway.ipipgo.com:9020",
"https" : "http://user:pass@gateway.ipipgo.com:9020"
}
session = Session()
response = session.get('https://api.example.com/products', proxies=proxy_config)
Il y a un champ de mines caché ici !
raw_data = json.loads(response.text)
Quatre conseils pour apprivoiser le JSON sauvage
Premier mouvement :Type de données Balayage. Utilisez cette opération soi lorsque vous rencontrez des champs de type mixte :
def clean_data(item).
Convertit uniformément les champs de prix en virgule flottante
if 'price' in item.
try.
item['prix'] = float(item['prix'])
except.
item['prix'] = 0.0
Tuiles de dictionnaires imbriqués
if 'specs' in item.
item.update(item.pop('specs'))
return item
safe_data = [clean_data(x) for x in raw_data['results']]]
Deuxième mouvement :Trifecta de rattrapage d'exceptions par proxy. Faites particulièrement attention aux fluctuations du réseau lorsque vous utilisez le proxy d'ipipgo :
| Type d'erreur | stratégie de réponse |
|---|---|
| Erreur de connexion | Commutation automatique des nœuds proxy |
| Délai d'attente | Attendre 3 à 5 secondes avant de réessayer |
| JSONDecodeError | Enregistrer le contenu de la réponse originale |
Fosses et gilets de sauvetage dans le monde réel
Une fois que j'ai utilisé le proxy à courte durée d'action d'ipipgo pour capturer des données, j'ai rencontré un JSON étrange - des émoticônes emoji dans le nom de la clé ! Cette fois-ci, n'utilisez pas la bibliothèque standard en dur, sur ce programme :
import demjson
from charset_normalizer import detect
Détecter le vrai encodage
encoding = detect(response.content)['encoding']
dirty_json = response.content.decode(encoding, errors='replace')
Analyse avec les bibliothèques triples
data = demjson.decode(dirty_json)
N'oubliez pas d'ajouter dans l'en-tête de la demande"Accept-Encoding" : "identité"Si vous souhaitez utiliser ce site web, certains sites web renvoient des données compressées, qui peuvent être altérées lorsque le proxy est relayé.
Temps consacré à l'assurance qualité (indispensable pour les débutants)
Q:Que dois-je faire si je continue à recevoir des JSON mutilés avec une IP proxy ?
R : 80% de la transmission est interceptée au milieu, nous suggérons : 1) de vérifier si le paquet de trafic d'ipipgo background est épuisé 2) d'ajouter "Connection" : "keep-alive" dans l'en-tête de la requête 3) d'augmenter le timeout à 10 secondes ou plus
Q : Quelle est l'astuce pour gérer plusieurs couches de JSON imbriquées ?
R : Utiliser jsonpath pour une poignée de navettes est bien plus cool que d'écrire plusieurs couches de boucles for :
from jsonpath_ng import parse
expr = parse('$..products[ ? (@.price > 100)].sku')
matches = [match.value for match in expr.find(data)]
Le jeu caché d'ipipgo
leurAgents de facturation à la demandeParticulièrement adapté au traitement de grandes quantités de données. Par exemple, si vous voulez soudainement analyser un fichier journal JSON de 10G, vous pouvez le faire :
import pandas as pd
from concurrent.futures import ThreadPoolExecutor
def parse_chunk(chunk).
avec ipipgo.create_session(duration='15min') as session.
return pd.json_normalize(chunk)
Traitement de fichiers volumineux par morceaux
résultats = []
with ThreadPoolExecutor(max_workers=5) as executor : for chunk in pd.read(chunk) : return pd.json_normalise(chunk)
for chunk in pd.read_json('bigfile.json', lines=True, chunksize=1000): :
results.append(executor.submit(parse_chunk, chunk))
Un dernier conseil : lorsqu'il s'agit de JSON, veillez àVérification du schéma avant l'analyse syntaxiqueSi vous utilisez le proxy d'ipipgo, vous pouvez utiliser la requête HEAD pour sonder d'abord la structure des données afin d'éviter de gaspiller du trafic. Si vous rencontrez un problème difficile, n'oubliez pas d'aller dans leurs documents pour leur remettre le "non-standard JSON processing guide", une arme qui vous sauvera la vie.

