見出し画像

【スクレイピング効率化】Proxy情報を収集するプログラムを作りました(http,https,Socks4,Socks5対応)

はい!どうもみなさん!

こんにちは。Ririkaです。
タイトルの建前ではスクレイピング効率化とか言っていますが、IPを変更しまくらないといけない特段の事情(意味深)にも便利です。

何故かというと、私自身も自作したスクリプトでニコニコ動画へのコメント大量連投に使っているからです。今のところ毎日40~50万のコメントが連投できます。改良の余地はあるかと思いますが、技術力がないもので開発スピードがおっそいおっそいのです。
まあそんな前置きはどうでもいいと思うので、注意事項だけ言っといて、本題のコードをさっさと配布しようと思います。
ついでに、Proxy(以下、串という)採集や検査において便利なソフトの紹介もしておきます。私はそのソフトと、この自作した串採集プログラムを併用してヒットする件数をなるだけ多くしています。

使用する際の注意事項

1.無料の串を採集してくるだけなので、匿名性はありません。断言します。無料の串に匿名性なんて概念はないので、暗号化されてるhttps串だろうが、全く信用に値しません。
つまりは、個人情報やアカウント情報なんかを使わないプログラムやテスト用にのみ組み込むべきです。

2.安全な有料VPNを経由してから串に情報を送りましょう。余裕でIPお漏らしするので、何か特段の事情(意味深)があって使う場合でも、生IPだと串から漏れた情報で開示されかねません。
かといってTor経由ではタイムアウトしまくって使い物にならないと思うので、VPNを一回刺すのが安牌です。
良心的なクロールプログラム(1秒に1回程度)のアクセスを行っていた方でさえ逮捕された事例がある(詳しくは下記のWikipediaのページを参照してください。)ので、串経由で相手側サイトの制限を突破するような行為を行うなら尚のこと気をつけないといけません。

3.このプログラムを使用して発生した責任や損害の補填は使用者が行うものとし、私は一切の責任を負いません。が、2で前述したようにVPNを正しく使用していればそんなことにはならないです。

4.使用前にはrequestsモジュールとpytzモジュールをインストールしておいてください。以下コピペ用

pip install requests

pip install pytz

http(s)を採集してくれる方

import requests
from datetime import datetime
import re
import time
import pytz

print("5つのサイトから、自動でHTTP(s) Proxyを取得するプログラムを開始します。\nCreated by Ririka\n(https://misskey.kindworld.one/@KisaragiRirika)\n")

url2 = "https://api.proxyscrape.com/proxytable.php"

response = requests.get(url2)
data = response.json()

http_proxies = data.get("http")

if http_proxies:
    proxies = []
    for proxy, _ in http_proxies.items():
        proxies.append(proxy)

    current_datetime = datetime.now()
    formatted_datetime = current_datetime.strftime('%Y-%m-%d_%H-%M')
    filename = f"httpProxies_{formatted_datetime}.txt"

    with open(filename, "w") as file:
        file.write("\n".join(proxies) + "\n")

    print(f"ProxyScrapeからの取得が完了しました。\nProxyを「{filename}」に保存しました。\n")
else:
    print("Proxy情報が見つかりませんでした。")

def extract_proxies(url):
    response = requests.get(url)
    proxy_data = response.text

    pattern = re.compile(r'\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}:\d+\b')

    proxy_list = re.findall(pattern, proxy_data)
    return proxy_list

proxy_url = "https://raw.githubusercontent.com/roosterkid/openproxylist/main/HTTPS.txt"

proxies = extract_proxies(proxy_url)

def append_proxies_to_file(filename, proxy_list):
    with open(filename, "a") as file:
        file.write("\n".join(proxy_list) + "\n")

append_proxies_to_file(filename, proxies)

print(f"RoostarKidからの取得が完了しました。\nProxyを「{filename}」に追記しました。\n")

proxy_url2 = "https://raw.githubusercontent.com/TheSpeedX/PROXY-List/master/http.txt"

http_response = requests.get(proxy_url2)
http_proxies = http_response.text.strip().split("\n")

with open(filename, "a") as file:
   file.write("\n".join(http_proxies) + "\n")

print(f"TheSpeedXからの取得が完了しました。\nProxyを「{filename}」に追記しました。\n")

moscow_timezone = pytz.timezone('Europe/Moscow')
current_datetime_moscow = datetime.now(moscow_timezone)
url_date = current_datetime_moscow.strftime('%Y-%m-%d')

url = f"https://checkerproxy.net/api/archive/{url_date}"
response = requests.get(url)
data = response.json()

proxy_list = []

for record in data:
    proxy_type = record.get("type")
    addr = record.get("addr")
    if proxy_type in [1, 2, 5] and addr:
        proxy_list.append(addr)

with open(filename, "a") as file:
    file.write("\n".join(proxy_list) + "\n")

print(f"CheckerProxyからの取得が完了しました。\nProxyを「{filename}」に追記しました。\n")

def extract_proxy_info(url):
    response = requests.get(url)
    data = response.json()

    proxy_list = []

    for entry in data.get("LISTA", []):
        ip = entry.get("IP")
        port = entry.get("PORT")
        if ip and port:
            proxy_list.append(f"{ip}:{port}")

    return proxy_list

http_url = "https://www.proxy-list.download/api/v2/get?l=en&t=http"
https_url = "https://www.proxy-list.download/api/v2/get?l=en&t=https"

http_proxies = extract_proxy_info(http_url)
https_proxies = extract_proxy_info(https_url)

with open(filename, "a") as file:
    file.write("\n".join(http_proxies + https_proxies))

print(f"Proxy-listからの取得が完了しました。\nProxyを「{filename}」に追記しました。\n")

def count_lines_in_file(filename):
    with open(filename, "r") as file:
        line_count = sum(1 for line in file)
    return line_count

line_count = count_lines_in_file(filename)

print(f"全てのProxy情報の取得が完了しました。取得できたHTTP(s) Proxyの数: {line_count}\nProxyリストを「{filename}」に保存しました。3秒後に終了します。")
time.sleep(3)

Socks4,5を収集してくれる方

import requests
from datetime import datetime
import re
import time
import pytz

print("7つのサイトから、自動でSocks4&5 Proxyを取得するプログラムを開始します。\nCreated by Ririka\n(https://misskey.kindworld.one/@KisaragiRirika)\n")

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/116.0',
    'Accept': '*/*',
    'Accept-Language': 'ja,en-US;q=0.7,en;q=0.3',
    'Referer': 'https://www.proxyrack.com/',
    'Origin': 'https://www.proxyrack.com',
    'DNT': '1',
    'Connection': 'keep-alive',
    'Sec-Fetch-Dest': 'empty',
    'Sec-Fetch-Mode': 'cors',
    'Sec-Fetch-Site': 'same-site',
    'Sec-GPC': '1',
}

params = {
    'perPage': '0',
    'offset': '0',
}

url = "https://proxyfinder.proxyrack.com/proxies.json?perPage=0&offset=0"

response = requests.get(url, params=params, headers=headers)
data = response.json()

proxies = []

for record in data['records']:
    ip = record.get('ip')
    port = record.get('port')
    if ip and port:
        proxies.append(f"{ip}:{port}")

current_datetime = datetime.now()
formatted_datetime = current_datetime.strftime('%m-%d_%H-%M')
filename = f"SocksProxies_{formatted_datetime}.txt"

with open(filename, "w") as file:
    file.write("\n".join(proxies) + "\n")

print(f"ProxyRackからの取得が完了しました。\nProxyリストを「{filename}」に保存しました。\n")

url = "https://api.proxyscrape.com/proxytable.php"

response = requests.get(url)
data = response.json()

socks4_proxies = data.get("socks4")
socks5_proxies = data.get("socks5")

all_socks_proxies = []

if socks4_proxies:
    all_socks_proxies.extend(socks4_proxies.keys())

if socks5_proxies:
    all_socks_proxies.extend(socks5_proxies.keys())

if all_socks_proxies:

    with open(filename, "a") as file:
        file.write("\n".join(all_socks_proxies) + "\n")

    print(f"ProxyScrapeからのProxy取得が完了しました。\nProxyを「{filename}」に追記しました。\n")
else:
    print("Proxy情報が見つかりませんでした。")

socks4_url = "https://raw.githubusercontent.com/TheSpeedX/PROXY-List/master/socks4.txt"
socks5_url = "https://raw.githubusercontent.com/TheSpeedX/PROXY-List/master/socks5.txt"

socks4_response = requests.get(socks4_url)
socks4_proxies = socks4_response.text.strip().split("\n")

socks5_response = requests.get(socks5_url)
socks5_proxies = socks5_response.text.strip().split("\n")

all_socks_proxies = socks4_proxies + socks5_proxies

if all_socks_proxies:
    with open(filename, "a") as file:
        file.write("\n".join(all_socks_proxies) + "\n")

    print(f"TheSpeedXからのProxy取得が完了しました。\nProxyを「{filename}」に追記しました。\n")
else:
    print("取得したProxy情報が見つかりませんでした。")

def extract_proxies(url):
    response = requests.get(url)
    proxy_data = response.text

    pattern = re.compile(r'\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}:\d+\b')

    proxy_list = re.findall(pattern, proxy_data)
    return proxy_list

socks4_url = "https://raw.githubusercontent.com/roosterkid/openproxylist/main/SOCKS4.txt"
socks5_url = "https://raw.githubusercontent.com/roosterkid/openproxylist/main/SOCKS5.txt"

socks4_proxies = extract_proxies(socks4_url)
socks5_proxies = extract_proxies(socks5_url)

def append_proxies_to_file(filename, proxy_list):
    with open(filename, "a") as file:
        file.write("\n".join(proxy_list) + "\n")

append_proxies_to_file(filename, socks4_proxies)
append_proxies_to_file(filename, socks5_proxies)

print(f"RoosterKidからの取得が完了しました。\nProxyを「{filename}」に追記しました。\n")

page_number = 1

def get_proxy_data(page_number):
    url = f"https://proxylist.geonode.com/api/proxy-list?limit=500&page={page_number}&sort_by=lastChecked&sort_type=desc"
    response = requests.get(url)
    data = response.json()
    return data

def extract_proxies2(data):
    proxies = []
    for record in data["data"]:
        ip = record.get("ip")
        port = record.get("port")
        if ip and port:
            proxy = f"{ip}:{port}"
            proxies.append(proxy)
    return proxies

print("※GeonodeからProxy情報を取得するのには少し時間がかかりますが、気長にお待ちください。\n")

while True:
    data = get_proxy_data(page_number)
    if not data["data"]:
        print(f"\nGeonodeからの取得が完了しました。\nProxyリストを「{filename}」に保存しました。\n")
        break

    proxies = extract_proxies2(data)
    with open(filename, "a") as file:
        file.write("\n".join(proxies) + "\n")
    
    print(f"GeonodeのAPIから、ページ {page_number} のProxy情報を取得して追記しました。")
    
    page_number += 1

moscow_timezone = pytz.timezone('Europe/Moscow')
current_datetime_moscow = datetime.now(moscow_timezone)
url_date = current_datetime_moscow.strftime('%Y-%m-%d')

url = f"https://checkerproxy.net/api/archive/{url_date}"
response = requests.get(url)
data = response.json()

proxy_list = []

for record in data:
    proxy_type = record.get("type")
    addr = record.get("addr")
    if proxy_type in [4] and addr:
        proxy_list.append(addr)

with open(filename, "a") as file:
    file.write("\n".join(proxy_list) + "\n")

print(f"CheckerProxyからの取得が完了しました。\nProxyを「{filename}」に追記しました。\n")

def extract_proxy_info(url):
    response = requests.get(url)
    data = response.json()

    proxy_list = []

    for entry in data.get("LISTA", []):
        ip = entry.get("IP")
        port = entry.get("PORT")
        if ip and port:
            proxy_list.append(f"{ip}:{port}")

    return proxy_list

socks4_url = "https://www.proxy-list.download/api/v2/get?l=en&t=socks4"
socks5_url = "https://www.proxy-list.download/api/v2/get?l=en&t=socks5"

socks4_proxies = extract_proxy_info(socks4_url)
socks5_proxies = extract_proxy_info(socks5_url)

with open(filename, "a") as file:
    file.write("\n".join(socks4_proxies + socks5_proxies))

print(f"Proxy-listからの取得が完了しました。\nProxyを「{filename}」に追記しました。\n")

def count_lines_in_file(filename):
    with open(filename, "r") as file:
        line_count = sum(1 for line in file)
    return line_count

line_count = count_lines_in_file(filename)

print(f"全てのProxy情報の取得が完了しました。取得できたSocks4&5 Proxyの数: {line_count}\nProxyリストを「{filename}」に保存しました。3秒後に終了します。")
time.sleep(3)

串採集補助ソフトの紹介

このソフトは山田偽研さんの個人開発で、難読化された、まあ悪く言えばスクレイピング対策で姑息なJavaScriptを仕込んで抵抗してくるウザいサイトからも串を採集できる、また数十本の串を一気に検査できるので、そんじょそこらの検査サイトと比べればめちゃめちゃ爆速で検査できます。とにかく、使ったらもう他には戻れない。ってレベルの利便性だから使ってみて!!

おすすめの使い方

Ver.0.74bで串収集機能は大幅強化されてるのですが、Ver.0.72bと違い目的のサイト(スクレイピング対象にしたいサイト)に実際にアクセスする機能が無くなってしまった(画像を参照)

Ver0.72


Ver0.74では検査先も選べない上に同時接続数も最大15に制限されており、正直改悪だと思います。


ので、0.74で収集した串を0.72にはっ付けて検査という手法が私のおすすめです。
それでは、長くなりましたが、これで紹介を終わらせていただきます。是非このスクリプトを楽しい(意味深)ことに使ってみてくださいね!


この記事が気に入ったらサポートをしてみませんか?