2017-02-03 10 views
0

Программа проверяет, приводит ли URL-адрес 404, и если он записывает имя пользователя в файл. Я попытался добавить многопроцессорность, чтобы программа работала быстрее, так как бывали случаи, когда я бы вводил текстовые файлы с 1000 строк, и это займет довольно много времени. Однако при первом запуске этой программы (когда выходной текстовый файл пуст), он ничего не записывает в выходной текстовый файл. Он только начинает записывать в выходной файл на 2-й, 3-й, 4-й ... запуск.Программа только записывает в файл при запуске после первого

#program checks twitch accounts in a file. 
#writes accounts which aren't taken to another file. 
import requests 
from multiprocessing import Pool 
x = "0" 

accounts = open('accounts.txt', 'r') 
valid_accounts = open('valid accounts.txt', 'a') 

base_url = "https://www.twitch.tv/" 

def check(x): 
    for line in accounts: 
     url = base_url + line 
     twitch_r = requests.get(url) 
     if twitch_r.status_code == 404: 
      valid_accounts.write(line + "\n") 



def Main(): 
    p = Pool(processes=25) 
    p.imap(check, x) 
    accounts.close() 
    valid_accounts.close() 



if __name__ == "__main__": 
    Main() 

ответ

0

Ваша главная проблема заключается в том, что вы используете imap вместо map. imap неблокируется, это означает, что ваш основной процесс завершается до того, как процессы пройдут. Я немного удивлен, что он работал иногда, как я думаю, он должен был работать never.

Тем не менее, есть несколько проблем с программой:

  • метода проверки, выполняющихся в различных процессах, акции один хендлер и перебирает линии. Это просто работает случайно (например, он не будет работать на Windows), и это плохая практика (чтобы поместить ее в середине). Сначала вы должны прочитать файл, а затем распространить строки на процессы.
  • То же самое относится к записи в файл. Хотя добавление к файлу безопасно и для разных процессов, лучшим вариантом было бы поместить это в конец в родительский процесс.
  • map и imap, как полагают, работают по списку аргументов, а затем возвращают результат (сопоставленный значение)
  • оставить из processes=20 так питона может узнать лучшее количество процессов на основе того, сколько ядер вашего компьютер имеет

Исходя из этих вещей, это код, который я предлагаю:

# program checks twitch accounts in a file. 
# writes accounts which aren't taken to another file. 
import requests 
from multiprocessing import Pool, Queue 

base_url = "https://www.twitch.tv/" 

def check(line): 
    twitch_r = requests.get(base_url + line) 
    if twitch_r.status_code == 404: 
     return line 

def Main(): 
    queue_in = Queue() 
    queue_out = Queue() 
    p = Pool() 

    with open('accounts.txt', 'r') as accounts: 
     lines = accounts.readlines() 

    results = p.map(check, lines) 
    results = [r for r in results if r != None] 
    with open('valid accounts.txt', 'a') as valid_accounts: 
     for result in results: 
      valid_accounts.write(result) 

if __name__ == "__main__": 
    Main() 

Единственное, что нужно отметить, это то, что вам нужно вырезать None в results, потому что check(line) возвращает None для всех URL-адресов, результатом которых является не 404.

Обновления:

После использования раствора Джона, программа работает по назначению

Я сомневаюсь, что это делает. Так как вы на окнах, каждый процесс имеет свой собственный файловый манипулятор, указывающий на accounts.txt и будет циклически перемещаться по всем линиям. Таким образом, вы в конечном итоге проверяете каждый URL-адрес 20 раз, и многопроцессорность не помогла вам

Я использовал imap, потому что читал, что imap не возвращает список (?)

No. Разница карты по сравнению с IMAP в этой ситуации только то, что карта ждет, пока не сделаны все процессы (таким образом, вам не нужно вызывать join).

Для более подробного обсуждения о карте против see here IMAP

+0

После использования решения Джона программа работает по назначению. Он работал над запусками после первого в Windows, прежде чем я что-то изменил. Я согласен с вами в том, что сначала должен был прочитать строки, а затем отправить их аргументам пула, но я не уверен, как сделать так, чтобы каждый процесс принимал другой аргумент. Если я создаю цикл for для каждой строки в файле, я бы использовал строку в качестве аргумента для моей функции пула, поэтому, если я не ошибаюсь, каждый процесс будет использовать тот же аргумент. Я использовал imap, потому что читал, что imap не возвращает список (?). 404 является правильным. – abc12333333

+0

@ abc12333333, если вы хотите использовать карту и сделать ее так, чтобы «каждый процесс принял другой аргумент», посмотрите на мое решение. Это именно то, что он делает. map берет одно значение из 'lines' и передает его на карту, а затем сохраняет' return' в 'results'. И это делается параллельно – hansaplast

+0

@ abc12333333 ваши другие вопросы, которые я добавил к моему ответу. О 404: теперь я изменил это, чтобы он делал то, что вы хотите. Пожалуйста, попробуйте мое решение выше, оно должно просто работать, оно работает на моей машине. – hansaplast

0

Вы должны позвонить p.close(), а затем p.join() в конце Main().

+0

Это фиксированный его. Я понимаю, что функция close используется, когда я больше не буду использовать пул, но я не уверен, что делает функция соединения. Из того, что я могу собрать, функция join ожидает завершения рабочих процессов, но не должен ли мой код быть законченным сразу после его завершения? Что ждать? – abc12333333

+0

@ abc12333333 'join()' ждет, пока все процессы не будут выполнены. Ваша программа выше запускает процессы и сразу же выходит из них и заставляет процессы умереть. – hansaplast

0

Вы не передавая свои счета в бассейн карте

p.imap(check, accounts) 
+0

Я думаю, что я плохо ее закодировал, но в коде, вышеперечисленном выше аргумента, передаваемого в мой пул .imap был просто случайным, потому что мне нужен аргумент. Сама функция проверки получала учетные записи из файла. – abc12333333