Я пытаюсь создать скрипт, который делает запросы на случайные URL-адреса из текстового файла

import urllib2

with open('urls.txt') as urls:
    for url in urls:
        try:
            r = urllib2.urlopen(url)
        except urllib2.URLError as e:
            r = e
        if r.code in (200, 401):
            print '[{}]: '.format(url), "Up!"
        elif r.code == 404:
            print '[{}]: '.format(url), "Not Found!" 

Но я хочу, чтобы когда какой-то URL-адрес 404 не был найден, удалите его из файла. Каждый URL-адрес в каждой строке, так что в основном это удалить каждый URL-адрес, который 404 не найден. Как это сделать?!

1
user1985563 24 Янв 2013 в 07:50

2 ответа

Лучший ответ

Чтобы удалить строки из файла, необходимо переписать все содержимое файла. Самый безопасный способ сделать это - записать новый файл в тот же каталог, а затем rename поверх старого файла. Я бы изменил ваш код следующим образом:

import os
import sys
import tempfile
import urllib2

good_urls = set()

with open('urls.txt') as urls:
    for url in urls:
        try:
            r = urllib2.urlopen(url)
        except urllib2.URLError as e:
            r = e
        if r.code in (200, 401):
            sys.stdout.write('[{}]: Up!\n'.format(url))
            good_urls.add(url)
        elif r.code == 404:
            sys.stdout.write('[{}]: Not found!\n'.format(url))
        else:
            sys.stdout.write('[{}]: Unexpected response code {}\n'.format(url, r.code))

tmp = None
try:
    tmp = tempfile.NamedTemporaryFile(mode='w', suffix='.txt', dir='.', delete=False)
    for url in sorted(good_urls):
        tmp.write(url + "\n")
    tmp.close()
    os.rename(tmp.name, 'urls.txt')
    tmp = None
finally:
    if tmp is not None:
        os.unlink(tmp.name)

Возможно, вы захотите добавить good_urls.add(url) к предложению else в первом цикле. Если кто-нибудь знает более аккуратный способ сделать то, что я сделал с try-finally там в конце, я хотел бы услышать об этом.

0
zwol 24 Янв 2013 в 04:01

Вы можете написать во второй файл:

import urllib2

with open('urls.txt', 'r') as urls, open('urls2.txt', 'w') as urls2:
    for url in urls:
        try:
            r = urllib2.urlopen(url)
        except urllib2.URLError as e:
            r = e

        if r.code in (200, 401):
            print '[{}]: '.format(url), "Up!"
            urls2.write(url + '\n')
        elif r.code == 404:
            print '[{}]: '.format(url), "Not Found!" 
1
Blender 24 Янв 2013 в 03:53