প্রতিটি প্রক্সি সারিকে একটি একক হিসেবে পার্স করুন। পৃষ্ঠার সব মিলে যাওয়া td একসাথে চ্যাপ্টা করে ফলাফল নির্দিষ্ট সংখ্যায় গোষ্ঠীবদ্ধ করলে, কোনো সেল অনুপস্থিত থাকলে বা আরেকটি টেবিল দেখা দিলে এক সারির ঠিকানা পরের সারির পোর্টের সঙ্গে জোড়া পড়তে পারে।

অ্যাপ্লিকেশন ইতিমধ্যে যে HTML পেয়েছে, তার প্রথম দুটি কলাম IP ঠিকানা ও পোর্ট এমন টেবিল এভাবে পার্স করা যায়:

import ipaddress
from bs4 import BeautifulSoup

soup = BeautifulSoup(html, "html.parser")
table = soup.select_one(table_selector)
if table is None:
    raise ValueError("Expected proxy table was not found")

endpoints = set()
for row in table.select("tbody tr"):
    cells = row.find_all("td", recursive=False)
    if len(cells) < 2:
        continue
    try:
        address = ipaddress.ip_address(cells[0].get_text(strip=True))
        port = int(cells[1].get_text(strip=True))
    except ValueError:
        continue
    if 1 <= port <= 65535:
        endpoints.add((str(address), port))

html এবং table_selector অ্যাপ্লিকেশনের ইনপুট। উৎসের প্রকৃত মার্কআপ দেখে সিলেক্টর ও কলাম ম্যাপিং বেছে নিন। বিনামূল্যের প্রক্সি তালিকা এন্ডপয়েন্ট রেকর্ডের একটি উৎস, তবে এই ম্যাপিং বেছে নেওয়ার আগে এর সারিগুলো পরীক্ষা করা উচিত। পুরনো টেবিল ID কিংবা কোনো পৃষ্ঠায় ঠিক 300 রেকর্ড আছে—এমন দাবি কোনো স্থায়ী স্কিমা নয়।

সেটটি প্রতিটি জোড়ার সংযোগ রেখেই পুনরাবৃত্ত ঠিকানা-পোর্ট জোড়া সরায়। অপ্রত্যাশিত শূন্য-ফলাফলের ইমপোর্ট তবুও তদন্ত করা উচিত: টেবিল বদলে থাকতে পারে, বা আনা নথিটি তালিকার বদলে একটি চ্যালেঞ্জ পৃষ্ঠা হতে পারে।

ঘোষিত প্রোটোকল ও পরীক্ষার সময়ের ফিল্ড থাকলে সেগুলো এন্ডপয়েন্টের সঙ্গে রাখুন। বিশ্বাসযোগ্য IP ও পোর্ট বের করা কেবল ফরম্যাট প্রমাণ করে, এন্ডপয়েন্ট এখন কাজ করা HTTP বা SOCKS সেবা দিচ্ছে তা নয়।

হেডার বা ফিল্টার সারি এন্ডপয়েন্ট নয়। শুধু th সেল থাকা সারি বাদ দেওয়া হয়, আর খালি বা ঠিকানা-নয় এমন ফিল্ড যাচাইয়ে ব্যর্থ হয়। অবস্থান দেখে প্রথম ও শেষ সারি ফেলে দেবেন না: পৃষ্ঠার লেআউট বদলালে দুটোর যেকোনোটি সত্যিকারের এন্ডপয়েন্ট হতে পারে।

সম্পর্কিত নিবন্ধ