Цель: Напишите средство для очистки экрана, которое будет проверять веб-страницы на предмет наличия на них определенного содержимого.

Метод: Имейте два файла конфигурации, один из которых содержит список URL-адресов, а другой - список строк для поиска. Откройте оба файла и прочтите их содержимое как два массива.

Цикл по массиву URL-адресов (назовем его Loop A).

Для каждого URL-адреса прочтите страницу с помощью urllib и разделите его на массив, разделив его на \ n. Прокрутите список строк (цикл B).

Для каждой строки в строках прокрутите строки HTML (цикл C) и в каждой строке выполните сопоставление с шаблоном. Запишите результаты в выходной файл, если найдено совпадение.

Проблема: Это нормально открывает файлы конфигурации. Петля А работает нормально. Петли B и C работают только на первом проходе петли A. На втором и третьем проходах петли A петля B не выполняется.

Простите за то, что вложил столько отладочного кода. Одна любопытная причуда заключается в том, что я вижу загадочную букву «b», появляющуюся в моем выводе, созданном строкой 52 кода.

Содержимое конфигурационного файла:

urls.txt

http://uk.norton.com
http://us.norton.com
http://ie.norton.com

targetStrings.txt

Norton Online Backup
Norton Ultimate Help Desk

Код:

# Import the modules we need
import urllib.request
import re

# Open the files we need
out = open('out.txt', 'w')
urls=open('urls.txt','r')
targetFile=open('targetStrings.txt','r',encoding=('utf-8'))

# function to take a URL, open the HTML, split it into an array, and return it
def getPage(url):
    return urllib.request.urlopen(url).read().decode().split('\n')

# function to kick out to an output file
def outFile(output):
    out.write(output + '\n')

# Function to test for matches    
def match(string, pageLine):
    if re.search(string.encode('utf-8'),pageLine):
        return True
    else:
        return False


#Loop through the URLs - Loop A
for url in urls:
    url=url.rstrip('\n')
    outFile('\nOpening ' + url) 
#    response=urllib.request.urlopen(url)
#    html=response.read().decode()
    html=getPage(str(url))
    if html !='':
        outFile('Page read successfully')
    else:
        outFile('Problem reading page')

    outFile(url + ' has ' + str(len(html)) + ' lines')

    #Loop through targetStrings - Loop B. This is only happening on the first pass of loop A.
    for line in targetFile:
        outFile('Beginning \'for line in targetFile:\' loop')
        line=line.rstrip('\n') #take out any \n newline characters at the end
        outFile('Looking for ' + line + ' in ' + url)
        foundCount=0

        # Loop through current HTML file - Loop C
        pageLineNumber=0
        for pageLine in html:
            pageLineNumber+=1
            pageLine=pageLine.encode('utf-8')
            outFile('Looking for ' + str(line) + ' in ' + str(pageLineNumber) + ' ' + str(pageLine))
            if match(line, pageLine):
                foundCount+=1
                outFile('FoundCount is ' + str(foundCount))
        outFile('Searched ' + str(pageLineNumber) + ' lines')

        if foundCount==0:
            outFile('Did not find ' + str(line))
        else:
            s=''
            if foundCount>0:
                s='s'
            outFile('Found ' + line + ' ' + str(foundCount) + ' time' + s)
            foundCount=0
f.close()
urls.close()
targetFile.close()

Eamonn Gormley

Ответов: 2

Ответы (2)

Проблема не в ваших вложенных циклах for. В для строки в targetFile: вы читаете targetFile на каждой итерации внешнего цикла. Вы не можете прочитать объект файла более одного раза, так как после полного чтения указатель чтения устанавливается на конец файла. Вам нужно либо создать новый файловый объект, либо использовать file_obj.seek (0), чтобы снова переместить указатель чтения в начало файла. Таким образом, вы можете добавить targetFile.seek (0) в качестве последней строки для внешнего цикла после строки for в targetFile: loop.

for url in urls:
    # outer loop code
    for line in targetFile:
        # inner loop code
    targetFile.seek(0)

f.close()
urls.close()
targetFile.close()

Другой и лучший вариант, предложенный @pvg, - это прочитать все строки в списке

targetLines=open('targetStrings.txt','r',encoding=('utf-8')).readlines()

и использовать этот список в дальнейшем

for line in targetLines:

Так как это будет эффективнее, чем читать файл снова и снова.

проблема в том, что когда вы впервые перебираете файл targetFile, указатель чтения в нем находится в конце файла, и когда вы снова пытаетесь выполнить цикл, вы ничего не получаете из этого, потому что вы уже в конце. Вы можете сделать 2 мысли, чтобы решить эту проблему

  1. поместите указатель чтения в начало с выполнением метода поиска targetFile.seek (0) до или после итерации по нему
  2. считывать целые строки файла в переменной и перебирать по ней.

2022 WebDevInsider