Python/크롤링

Python Free Proxy 사용하기

코코로코코 2023. 5. 9. 21:30
반응형

지난번 던파 프로젝트를 진행하고나서 더 궁금해졌던 것은 유저들의 즉각적인 반응이었다.

 

그래서 이번에는 던전앤파이터에서 잘 알려진 커뮤니티인 던파 조선, 지하성과 용사 마이너 갤러리, 아카라이브의 게시글을 크롤링 해보기로 했다.

 

그런데 문제가 생긴게 게시글에  대한 정보를 받아오고 내용을 받아오려고 하니 요청이 너무 많아져서 블락에 걸려버렸다...

 

그래서 해결 방법을 찾은것이 Proxy를 사용하는 것이다.  타  무료 Proxy는 사용하기에는 이미 제공을 하지 않는 것  같았다. 그러던 중에  찾은 것이 아래 사이트다.

https://spys.one/en/free-proxy-list/

 

Free proxy list, public proxy servers list online, live proxies

 

spys.one

 

이번글에서는 위 사이트에서 제공해주는 무료 Proxy를 크롤링하는 과정만 다룹니다.

 

우선  위 링크에 접속하면 아래와 같이 나온다.

 

위 페이지에서 한 번 정보를 가져오면 될 것이라 생각해서

url = 'https://spys.one/en/free-proxy-list/'

BeautifulSoup(requests.get(url).text, 'html.parser')

이 코드를 실행해보면 위에 사진에 있는 IP와 포트, Proxy Type 등 다양한 정보들이 없다....

 

오른쪽 상단을 보면 선택박스 부분이 있는데 이 사이트는 폼형태로 되어 있어서 이를 전달해줘야했었다.

 

그래서 아래와 같이 내용을 추가해준다면

url = 'http://spys.one/en/free-proxy-list/'

data = {
    'xpp' : '1',
    'xf1' : '0',
    'xf2' : '0',
    'xf4' : '0',
    'xf5' : '2'
}

headers = {
        'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36'
}

r = requests.post(url, data=data, headers=headers)

BeautifulSoup(r.content, 'html.parser')

 script안에 정보가 담겨있다.

 

근데 사이트 제작자가 악질인지 포트를 숨겨놨다... 그래서 위 코드로 실행하면 IP주소는 얻을 수 있는데 포트를 알수가 없었다. 근데 그렇게 장난쳐놓은 정보도 가져온 데이터 안에 숨겨져 있었다...ㅠ

script = soup.select_one('body > script')
for row in script.text.split(';'):
    if '^' in row:
        print(row)

------

t0d4i9=0^q7s9
u1w3m3=1^d4v2
p6s9o5=2^g7n4
w3k1p6=3^l2r8
n4z6s9=4^t0i9
k1q7y5=5^e5t0
g7x4f6=6^f6l2
v2r8v2=7^z6k1
i9o5q7=8^r8u1
s9g7e5=9^u1g7

위 코드를 실행하면 점선 밑의 결과가 나온다.  '=' 뒤에 0~9까지 숫자가 있다. 이렇게 숨겨서 표시해놨다... 그래서 단순하게 숫자, 포트로 찾으면 찾을 수가 없었따... 이를 사전으로 만들고 그 정보를 추가하게끔 만들었다.

 

또한 아무 Proxy를 쓰기보다 속도가 빠른게 필요했기 때문에 Latency가 높은순으로 정렬하여 크롤링한 Proxy 정보를  가져오게 했다. 그런데 Latency에서 또 숫자만 가져오는게 아니었다... 새로운 proxy가 생기면 숫자가 아니라 new-로 표시되고 있어서 이부분은 그냥 가져오지 않게 했다.

 

def get_proxy_list():
    url = 'http://spys.one/en/free-proxy-list/'
    data = {
        'xpp' : '1',
        'xf1' : '0',
        'xf2' : '0',
        'xf4' : '0',
        'xf5' : '2'
    }

    headers = {
        'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36'
    }

    r = requests.post(url, data=data, headers=headers)

    soup = BeautifulSoup(r.content, 'html.parser')
    
    result = []
    
    ports = {}
    script = soup.select_one('body > script')
    for row in script.text.split(';'):
        if '^' in row:
            line = row.split('=')
            ports[line[0]]  = line[1].split('^')[0]
            
    trs = soup.select('tr[onmouseover]')
    for tr in trs:
        
        is_http = tr.select_one('a')
        
        if is_http is not None:
            http = is_http.text
        
        e_ip = tr.select_one('font.spy14')
        ip = ''
        
        e_port = tr.select_one('script')
        port = ''
        if e_port is not None:
            re_port = re.compile(r'\(([a-zA-Z0-9]+)\^[a-zA-Z0-9]+\)')
            match = re_port.findall(e_port.text)
            for item in match:
                port = port + ports[item]
        else:
            continue

        if e_ip is not None:
            for item in e_ip.findAll('script'):
                item.extract()
            ip = e_ip.text
            
        else:
            continue
            
        tds = tr.select("td")
        is_skip = False
        for td in tds:
            e_pct = td.select_one('font > acronym')
            if e_pct is not None:
                pct = re.sub('([0-9]+)%.*', r'\1', e_pct.text)
                if not pct.isdigit():
                    is_skip = True
            else:
                continue
        
        if not pct.isdigit():
            continue
            
        result.append((http,ip + ':' + port, pct))
        
    result.sort(key = lambda element  : int(element[2]), reverse=True)
            
    return result

 

그래서 최종적으로 (Proxy type, Adress:Port, Latency)이렇게 튜플로 받아오게끔 했다. 결과는 아래와 같다.

 

 

+(추가 진행 사항)

Proxy 정보를 가져오는데만 하루를 통을 썼다. 그런데 또 직면한게 Proxy 마다 데이터를  가져오는 속도가 좀 달랐다.. 이 부분에 대해서는  좀 더 고민해봐야겠다. 여튼 이렇게 가져온 Proxy로 지하와 용사 갤러리 게시글 클롤링을 진행해봤다. Proxy 연결 속도가 달라서 가져오는 속도가 일정하지  않아서 이부분에 대해서는 좀 더 찾아봐야할듯...

 

반응형