Найти - Пользователи
Полная версия: 500 WMR за совет
Начало » Python для новичков » 500 WMR за совет
1
russian_bear
Друзья, всем привет!
Очень нужен совет по теме ниже, с радостью заплачу 500 WMR первому кто укажет работающий код.
Суть проблемы - нужно максимально ускорить выполнение скрипта, который обходит веб-адреса по списку “domains.txt”, указывая при этом в качестве ссылающегося адреса (referer) один определенный домен. Я написал скрипт который это делает последовательно, обходя домены один за другим, теперь мне нужно многократно ускорить работу этого скрипта. Это можно сделать за счет параллельного выполнения нескольких запросов, чем больше параллельных запросов - тем лучше. По запросу “python multithreading url” google выдает кучу разных решений, но ни один из них к сожалению у меня не заработал, видимо руки из ж… растут Вот например несколько примеров:
http://chriskiehl.com/article/parallelism-in-one-line/
https://mellowd.co.uk/ccie/?tag=multi-threading
http://stackoverflow.com/questions/16181121/python-very-simple-multithreading-parallel-url-fetching-without-queue
Мой скрипт указан ниже, он выполняется минут за 5, мне нужно максимально ускорить его работу, я предполагаю что путем распараллеливания задач можно ускорить работу минимум в 5-10 раз. (предполагаем что комп и Интернет - мощные и не вносят задержек)
import urllib2
my_ref = "http://sun-charge.com/" #zdes budem moi domen, drugoi
with open("domains.txt", "r") as f:
    urls = f.readlines()
 
for url in urls:
    url = url.strip()
    url = "http://" + url
    try:
        opener = urllib2.build_opener()
        opener.addheaders = [('Referer', my_ref)] #dlya proverki mozhno pomenyat mestami "url" i "my_ref"
        opener.open(url) #dlya proverki mozhno pomenyat mestami "url" i "my_ref"
        print "done"
    except:
        print "Unable to download"
Для проверки срабатывания подмены реферера можно использовать сайт http://sun-charge.com/ т.к. его статистика открыта и доступна по адресу http://www.sun-charge.com/bbclone/show_detailed.php
Т.е. если в моем скрипте поменять местами переменные “my_ref” и “url” в тех строчках где указаны соответствующие комменты, но прогон будет выполняться только по домену sun-charge.com а в качестве реферера будут указаны домены из списка “domains.txt”, если в статистике по адресу http://www.sun-charge.com/bbclone/show_detailed.php вы увидели любой домен из списка “domains.txt” - значит все работает ОК.
Т.е. еще раз кратко суть - написать скрипт с тем-же смыслом что и мой вариант выше, но обходящий домены не последовательно один за одним, а параллельно выполняющий много запросов(чем больше - тем лучше) чтобы достичь минимум 5-10 кратного ускорения работы относительно моего варианта.
С меня в качестве “спасибо” 500 WMR первому, кто напишет РАБОТАЮЩИЙ код.

заранее большое спасибо !!!
py.user.next
Надо просто загрузить в queue.Queue() ссылки и запустить множество потоков, читающих с неё.

russian_bear
http://chriskiehl.com/article/parallelism-in-one-line/
https://mellowd.co.uk/ccie/?tag=multi-threading
http://stackoverflow.com/questions/16181121/python-very-simple-multithreading-parallel-url-fetching-without-queue
Это всё не то. Вот пример.
russian_bear
py.user.next
Надо просто загрузить в queue.Queue() ссылки и запустить множество потоков, читающих с неё.
К сожалению у меня не хватает опыта(и ума?) переписать скрипт самостоятельно, использую пример с “Queue” . Буду бесконечно благодарен(и 500 WMR) любому кто даст готовый работающий вариант.
заранее большое спасибо !!!
PooH
Как то так
import urllib2
from queue import Queue
from threading import Thread
 
MY_REF = "http://sun-charge.com/"
NUM_THREADS = 8
 
def chech_url(queue):
    while True:
        url = queue.get()
        try:
            opener = urllib2.build_opener()
            opener.addheaders = [('Referer', MY_REF)]
            opener.open(url)
            print("done")
        except Exception as e:
            print("Unable to download", e)
        queue.task_done()
 
check_queue = Queue()
 
with open("/home/pooh/domains.txt", "r") as f:
    for url in f:
        check_queue.put("http://{0}".format(url.strip()))
 
for i in range(NUM_THREADS):
    worker = Thread(target=chech_url, args=(check_queue,))
    worker.setDaemon(True)
    worker.start()
 
check_queue.join()
russian_bear
PooH
Как то так
Дорогой PooH,
1)спасибо большое за код
2)к сожалению он не работает
при попытке запуска скрипта - ошибка типа “Exception in thread Thread-7 (most likely raised during interpreter shutdown)”
http://jci-congress.net/error.png

Погуглил на тему, пишут что не рекомендуют делать “daemon = True” (http://stackoverflow.com/questions/20596918/python-exception-in-thread-thread-1-most-likely-raised-during-interpreter-shutd) , заменил worker.setDaemon(True) на worker.setDaemon(False), не помогло
russian_bear
кстати помогает если вообще закомментировать(или стереть) строчку “worker.setDaemon(True)”, скрипт НАЧИНАЕТ исполняться, но через несколько секунд подвисает и останавливается в выполнении(без ошибки), визуально как если-бы задание (thread) встало в очередь а она остановилась из-за ожидания ответа получения урл
ayb
Сдался Вам этот urllib ? Вот можете попробовать. Поэкспериментируйте со значением timeout.

import requests
from multiprocessing.dummy import Pool
import time
ref = 'http://sun-charge.com/'
def get_url(url):
    try:
        requests.get('http://%s' % url.rstrip(), timeout=1, headers={'referer': ref})
        print('done')
    except Exception as e:
        print(e)
domains = open('/home/ayb/Загрузки/domains.txt', 'r').readlines()
pool = Pool(200)
pool.map(get_url, domains)

У меня вышло 47 секунд.

russian_bear
ayb
Сдался Вам этот urllib ? Вот можете попробовать. Поэкспериментируйте со значением timeout.
Спасибо, дружище !!! То что надо ! респект и уважуха. Напиши пожалуйста номер WMR кошелька.(можно в ЛС)
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB