Невозможно передать прокси и ссылки на пул потоков, чтобы получить результаты - PullRequest
0 голосов
/ 27 декабря 2018

Я написал скрипт на python, используя прокси для очистки ссылок разных постов, проходящих через разные страницы веб-страницы.Я пытался использовать proxies из списка.Предполагается, что скрипт берет случайное значение proxies из списка и отправляет запрос на этот сайт и, наконец, анализирует элементы.Однако, если какой-либо proxy не работает, его следует исключить из списка.

Я думал, что способ, которым я использовал number of proxies и list of urls в ThreadPool(10).starmap(make_requests, zip(proxyVault,lead_url)), точен, но это нене дает никаких результатов;скорее, скрипт застревает.

Как я могу передать прокси и ссылки на ThreadPool для того, чтобы скрипт дал результаты?

import requests
from bs4 import BeautifulSoup
from urllib.parse import urljoin
from multiprocessing.pool import ThreadPool
from itertools import cycle
import random

base_url = 'https://stackoverflow.com/questions/tagged/web-scraping'
lead_url = ["https://stackoverflow.com/questions/tagged/web-scraping?sort=newest&page={}&pagesize=15".format(page) for page in range(1,6)]

proxyVault = ['104.248.159.145:8888', '113.53.83.252:54356', '206.189.236.200:80', '218.48.229.173:808', '119.15.90.38:60622', '186.250.176.156:42575']

def make_requests(proxyVault,lead_url):
    while True:
        random.shuffle(proxyVault)
        global pitem   
        pitem = cycle(proxyVault)
        proxy = {'https':'http://{}'.format(next(pitem))}
        try:
            res = requests.get(lead_url,proxies=proxy)
            soup = BeautifulSoup(res.text,"lxml")
            [get_title(proxy,urljoin(base_url,item.get("href"))) for item in soup.select(".summary .question-hyperlink")]
        except Exception:
            try: 
                proxyVault.pop(0)
                make_requests(proxyVault,lead_url)
            except Exception:pass

def get_title(proxy,itemlink):
    res = requests.get(itemlink,proxies=proxy)
    soup = BeautifulSoup(res.text,"lxml")
    print(soup.select_one("h1[itemprop='name'] a").text)

if __name__ == '__main__':
    ThreadPool(10).starmap(make_requests, zip(proxyVault,lead_url))

Кстати, proxies, использованное выше, является просто заполнителями.

Ответы [ 2 ]

0 голосов
/ 29 декабря 2018

Проблемы с вашим кодом заключались в том, что он создавал множество бесконечных циклов в потоке.То, как вы работали с прокси-серверами, было для меня немного странным, поэтому я изменил это.Я также думаю, что вы неправильно поняли, как данные отправлялись в потоки, они получают один элемент итерируемого, а не все.Поэтому я изменил некоторые имена, чтобы отразить это.

Теперь он работает так, что каждый поток получает свой собственный url из lead_url, а затем выбирает случайный прокси из proxyVault.Они выбирают веб-страницу, анализируют ее и вызывают get_title для каждой из проанализированных ссылок.

Если запрос не выполняется из-за прокси-сервера, этот прокси-сервер удаляется из списка, поэтому он не используется снова и вызывается make_requests,который случайным образом выберет новый прокси из тех, которые все еще доступны.Я не изменил фактический синтаксический анализ, потому что я не могу судить, если это то, что вы хотите или нет.

Runnable код:

https://repl.it/@zlim00/unable-to-pass-proxies-and-links-to-the-threadpool-to-get-re

from bs4 import BeautifulSoup
from multiprocessing.pool import ThreadPool
from random import choice
import requests
from urllib.parse import urljoin

base_url = 'https://stackoverflow.com/questions/tagged/web-scraping'
lead_url = [f'https://stackoverflow.com/questions/tagged/web-scraping?sort='
            f'newest&page={page}&pagesize=15' for page in range(1, 6)]

proxyVault = ['36.67.57.45:53367', '5.202.150.233:42895',
              '85.187.184.129:8080', '109.195.23.223:45947']

def make_requests(url):
    proxy_url = choice(proxyVault)
    proxy = {'https': f'http://{proxy_url}'}
    try:
        res = requests.get(url, proxies=proxy)
        soup = BeautifulSoup(res.text, "lxml")
        [get_title(proxy, urljoin(base_url, item.get("href")))
         for item in soup.select(".summary .question-hyperlink")]
    except requests.exceptions.ProxyError:
        # Check so that the bad proxy was not removed by another thread
        if proxy_url in proxyVault:
            proxyVault.remove(proxy_url)
            print(f'Removed bad proxy: {proxy_url}')
        return make_requests(url)

def get_title(proxy, itemlink):
    res = requests.get(itemlink, proxies=proxy)
    soup = BeautifulSoup(res.text, "lxml")
    print(soup.select_one("h1[itemprop='name'] a").text)

if __name__ == '__main__':
    ThreadPool(10).map(make_requests, lead_url)
0 голосов
/ 27 декабря 2018

Может быть, вы можете использовать другой подход для получения прокси, как этот

def get_proxy():                                                                                                                                                                                  
    url = 'https://free-proxy-list.net/anonymous-proxy.html'                                                                                                                                      
    response = requests.get(url)                                                                                                                                                                  
    soup = BeautifulSoup(response.text, 'lxml')                                                                                                                                                   
    table = soup.find('table', attrs={'id': 'proxylisttable'})                                                                                                                                    
    table_body = table.find('tbody')                                                                                                                                                              
    proxies = table_body.find_all('tr')                                                                                                                                                           
    proxy_row = random.choice(proxies).find_all('td')                                                                                                                                             
    return proxy_row[0].text + ':' + proxy_row[1].text  
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...