So gut diese Methode der Datenerfassung auch zu sein scheint, sie wird von vielen Websites missbilligt, und es gibt Konsequenzen für das Scraping, wie z. B. eine Sperrung unserer IP.
Positiv zu vermerken ist, dass Proxy-Dienste helfen, diese Folgen zu vermeiden. Sie ermöglichen es uns, beim Sammeln von Daten im Internet eine andere IP-Adresse zu verwenden, und so sicher dies auch zu sein scheint, ist die Verwendung mehrerer Proxys besser. Die Verwendung mehrerer Proxys beim Scraping lässt die Interaktion mit der Website zufällig erscheinen und erhöht die Sicherheit.
Die Ziel-Website (Quelle) für diesen Leitfaden ist eine Online-Buchhandlung. Sie imitiert eine E-Commerce-Website für Bücher. Auf ihr sind Bücher mit Namen, Preis und Verfügbarkeit zu finden. Da es in diesem Leitfaden nicht um die Organisation der zurückgegebenen Daten geht, sondern um die Rotation von Proxys, werden die zurückgegebenen Daten nur in der Konsole dargestellt.
Installieren und importieren Sie einige Python-Module in unsere Datei, bevor wir mit der Codierung der Funktionen beginnen können, die beim Rotieren der Proxys und beim Scraping der Website helfen sollen.
pip install requests beautifulSoup4 lxml
3 der 5 Python-Module, die für dieses Scraping-Skript benötigt werden, können mit dem obigen Befehl installiert werden. Requests ermöglicht es uns, HTTP-Anfragen an die Website zu senden, beautifulSoup4 erlaubt es uns, die von Requests gelieferten Informationen aus dem HTML der Seite zu extrahieren, und LXML ist ein HTML-Parser.
Außerdem benötigen wir das eingebaute Threading-Modul, um mehrere Tests der Proxys zu ermöglichen, um zu sehen, ob sie funktionieren, und json, um aus einer JSON-Datei zu lesen.
import requests
import threading
from requests.auth import HTTPProxyAuth
import json
from bs4 import BeautifulSoup
import lxml
import time
url_to_scrape = "https://books.toscrape.com"
valid_proxies = []
book_names = []
book_price = []
book_availability = []
next_button_link = ""
Um ein Scraping-Skript zu erstellen, das Proxys rotieren lässt, benötigen wir eine Liste von Proxys, aus der wir während der Rotation auswählen können. Einige Proxys erfordern eine Authentifizierung, andere nicht. Wir müssen eine Liste von Wörterbüchern mit Proxy-Details erstellen, einschließlich des Proxy-Benutzernamens und -Passworts, falls eine Authentifizierung erforderlich ist.
Am besten ist es, die Proxy-Informationen in einer separaten JSON-Datei zu speichern, die wie die folgende Datei aufgebaut ist:
[
{
"proxy_address": "XX.X.XX.X:XX",
"proxy_username": "",
"proxy_password": ""
},
{
"proxy_address": "XX.X.XX.X:XX",
"proxy_username": "",
"proxy_password": ""
},
{
"proxy_address": "XX.X.XX.X:XX",
"proxy_username": "",
"proxy_password": ""
},
{
"proxy_address": "XX.X.XX.X:XX",
"proxy_username": "",
"proxy_password": ""
}
]
Geben Sie in das Feld "proxy_address" die IP-Adresse und den Port ein, getrennt durch einen Doppelpunkt. In den Feldern "proxy_username" und "proxy_password" geben Sie den Benutzernamen und das Passwort für die Autorisierung an.
Oben sehen Sie den Inhalt einer JSON-Datei mit 4 Proxys, aus denen das Skript wählen kann. Der Benutzername und das Passwort können leer sein, um einen Proxy anzugeben, der keine Authentifizierung erfordert.
def verify_proxies(proxy:dict):
try:
if proxy['proxy_username'] != "" and proxy['proxy_password'] != "":
proxy_auth = HTTPProxyAuth(proxy['proxy_username'], proxy['proxy_password'])
res = requests.get(
url_to_scrape,
auth = proxy_auth,
proxies={
"http" : proxy['proxy_address']
}
)
else:
res = requests.get(url_to_scrape, proxies={
"http" : proxy['proxy_address'],
})
if res.status_code == 200:
valid_proxies.append(proxy)
print(f"Proxy Validated: {proxy['proxy_address']}")
except:
print("Proxy Invalidated, Moving on")
Als Vorsichtsmaßnahme stellt diese Funktion sicher, dass die bereitgestellten Proxys aktiv sind und funktionieren. Wir können dies erreichen, indem wir jedes Wörterbuch in der JSON-Datei in einer Schleife durchlaufen, eine GET-Anfrage an die Website senden und, wenn ein Statuscode von 200 zurückgegeben wird, diesen Proxy zur Liste der valid_proxies hinzufügen - eine Variable, die wir zuvor erstellt haben, um die funktionierenden Proxys aus der Liste in der Datei aufzunehmen. Wenn der Aufruf nicht erfolgreich ist, wird die Ausführung fortgesetzt.
Da beautifulSoup den HTML-Code der Website benötigt, um die benötigten Daten zu extrahieren, haben wir request_function() erstellt, die die URL und den Proxy der Wahl entgegennimmt und den HTML-Code als Text zurückgibt. Die Proxy-Variable ermöglicht es uns, die Anfrage durch verschiedene Proxys zu leiten und somit den Proxy zu drehen.
def request_function(url, proxy):
try:
if proxy['proxy_username'] != "" and proxy['proxy_password'] != "":
proxy_auth = HTTPProxyAuth(proxy['proxy_username'], proxy['proxy_password'])
response = requests.get(
url,
auth = proxy_auth,
proxies={
"http" : proxy['proxy_address']
}
)
else:
response = requests.get(url, proxies={
"http" : proxy['proxy_address']
})
if response.status_code == 200:
return response.text
except Exception as err:
print(f"Switching Proxies, URL access was unsuccessful: {err}")
return None
data_extract() extrahiert die Daten, die wir benötigen, aus dem bereitgestellten HTML-Code. Sie sammelt das HTML-Element, das die Buchinformationen wie den Namen des Buches, den Preis und die Verfügbarkeit enthält. Außerdem wird der Link zur nächsten Seite extrahiert.
Dies ist besonders knifflig, weil der Link dynamisch ist, so dass wir die Dynamik berücksichtigen mussten. Schließlich werden die Bücher durchsucht und der Name, der Preis und die Verfügbarkeit extrahiert. Anschließend wird der Link für die nächste Schaltfläche zurückgegeben, mit dem wir den HTML-Code der nächsten Seite abrufen würden.
def data_extract(response):
soup = BeautifulSoup(response, "lxml")
books = soup.find_all("li", class_="col-xs-6 col-sm-4 col-md-3 col-lg-3")
next_button_link = soup.find("li", class_="next").find('a').get('href')
next_button_link=f"{url_to_scrape}/{next_button_link}" if "catalogue" in next_button_link else f"{url_to_scrape}/catalogue/{next_button_link}"
for each in books:
book_names.append(each.find("img").get("alt"))
book_price.append(each.find("p", class_="price_color").text)
book_availability.append(each.find("p", class_="instock availability").text.strip())
return next_button_link
Um alles miteinander zu verknüpfen, müssen wir:
with open("proxy-list.json") as json_file:
proxies = json.load(json_file)
for each in proxies:
threading.Thread(target=verify_proxies, args=(each, )).start()
time.sleep(4)
for i in range(len(valid_proxies)):
response = request_function(url_to_scrape, valid_proxies[i])
if response != None:
next_button_link = data_extract(response)
break
else:
continue
for proxy in valid_proxies:
print(f"Using Proxy: {proxy['proxy_address']}")
response = request_function(next_button_link, proxy)
if response is not None:
next_button_link = data_extract(response)
else:
continue
for each in range(len(book_names)):
print(f"No {each+1}: Book Name: {book_names[each]} Book Price: {book_price[each]} and Availability {book_availability[each]}")
import requests
import threading
from requests.auth import HTTPProxyAuth
import json
from bs4 import BeautifulSoup
import time
url_to_scrape = "https://books.toscrape.com"
valid_proxies = []
book_names = []
book_price = []
book_availability = []
next_button_link = ""
def verify_proxies(proxy: dict):
try:
if proxy['proxy_username'] != "" and proxy['proxy_password'] != "":
proxy_auth = HTTPProxyAuth(proxy['proxy_username'], proxy['proxy_password'])
res = requests.get(
url_to_scrape,
auth=proxy_auth,
proxies={
"http": proxy['proxy_address'],
}
)
else:
res = requests.get(url_to_scrape, proxies={
"http": proxy['proxy_address'],
})
if res.status_code == 200:
valid_proxies.append(proxy)
print(f"Proxy Validated: {proxy['proxy_address']}")
except:
print("Proxy Invalidated, Moving on")
# Ruft das HTML-Element einer Seite ab
def request_function(url, proxy):
try:
if proxy['proxy_username'] != "" and proxy['proxy_password'] != "":
proxy_auth = HTTPProxyAuth(proxy['proxy_username'], proxy['proxy_password'])
response = requests.get(
url,
auth=proxy_auth,
proxies={
"http": proxy['proxy_address'],
}
)
else:
response = requests.get(url, proxies={
"http": proxy['proxy_address'],
})
if response.status_code == 200:
return response.text
except Exception as err:
print(f"Switching Proxies, URL access was unsuccessful: {err}")
return None
# Kratzen
def data_extract(response):
soup = BeautifulSoup(response, "lxml")
books = soup.find_all("li", class_="col-xs-6 col-sm-4 col-md-3 col-lg-3")
next_button_link = soup.find("li", class_="next").find('a').get('href')
next_button_link = f"{url_to_scrape}/{next_button_link}" if "catalogue" in next_button_link else f"{url_to_scrape}/catalogue/{next_button_link}"
for each in books:
book_names.append(each.find("img").get("alt"))
book_price.append(each.find("p", class_="price_color").text)
book_availability.append(each.find("p", class_="instock availability").text.strip())
return next_button_link
# Proxy aus JSON abrufen
with open("proxy-list.json") as json_file:
proxies = json.load(json_file)
for each in proxies:
threading.Thread(target=verify_proxies, args=(each,)).start()
time.sleep(4)
for i in range(len(valid_proxies)):
response = request_function(url_to_scrape, valid_proxies[i])
if response is not None:
next_button_link = data_extract(response)
break
else:
continue
for proxy in valid_proxies:
print(f"Using Proxy: {proxy['proxy_address']}")
response = request_function(next_button_link, proxy)
if response is not None:
next_button_link = data_extract(response)
else:
continue
for each in range(len(book_names)):
print(
f"No {each + 1}: Book Name: {book_names[each]} Book Price: {book_price[each]} and Availability {book_availability[each]}")
Nach erfolgreicher Ausführung sehen die Ergebnisse wie unten dargestellt aus. Anschließend werden Informationen zu über 100 Büchern unter Verwendung der 2 bereitgestellten Proxys extrahiert.
Die Verwendung mehrerer Proxys für das Web-Scraping ermöglicht es, die Anzahl der Anfragen an die Zielressource zu erhöhen und die Blockierung zu umgehen. Um die Stabilität des Scraping-Prozesses aufrechtzuerhalten, ist es ratsam, IP-Adressen zu verwenden, die eine hohe Geschwindigkeit und einen starken Vertrauensfaktor bieten, wie z. B. statische ISP- und dynamische Resident-Proxys. Darüber hinaus kann die Funktionalität des bereitgestellten Skripts leicht erweitert werden, um verschiedenen Anforderungen an das Scraping von Daten gerecht zu werden.
Мы получили вашу заявку!
Ответ будет отправлен на почту в ближайшее время.
С уважением proxy-seller.ru!
Bemerkungen: 0