Как сравнить элемент в очереди с элементом в наборе? - PullRequest
1 голос
/ 01 ноября 2010

REDIT: пытался избежать размещения всего блока кода на форуме и сказать, что исправьте это для меня, но здесь, просто для определения ошибки:

#! /usr/bin/python2.6
import threading
import Queue
import sys
import urllib
import urllib2
from urlparse import urlparse
from lxml.html import parse, tostring, fromstring

THREAD_NUMBER = 1


class Crawler(threading.Thread):

 def __init__(self, queue, mal_urls, max_depth):
    self.queue = queue
    self.mal_list = mal_urls
    self.crawled_links = []
    self.max_depth = max_depth
    self.count = 0 
    threading.Thread.__init__(self) 

 def run(self):
    while True:
        if self.count <= self.max_depth:
            self.crawled = set(self.crawled_links)
            url = self.queue.get()
            if url not in self.mal_list:
                self.count += 1
                self.crawl(url)
            else:
                #self.queue.task_done()
                print("Malicious Link Found: {0}".format(url))
                continue
        else:
            self.queue.task_done()
            break
    print("\nFinished Crawling! Reached Max Depth!")
    sys.exit(2)

def crawl(self, tgt):
    try:
        url = urlparse(tgt)
        self.crawled_links.append(tgt)
        print("\nCrawling {0}".format(tgt))
        request = urllib2.Request(tgt)
        request.add_header("User-Agent", "Mozilla/5,0")
        opener = urllib2.build_opener()
        data = opener.open(request)

    except: # TODO: write explicit exceptions the URLError, ValueERROR ...
        return

    doc = parse(data).getroot()
    for tag in doc.xpath("//a[@href]"):
        old = tag.get('href')
        fixed = urllib.unquote(old)
        self.queue_links(fixed, url)


 def queue_links(self, link, url):

    if link.startswith('/'):
        link = "http://" + url.netloc + link

    elif link.startswith("#"):
        return

    elif not link.startswith("http"):
        link = "http://" + url.netloc + "/" + link


    if link not in self.crawled_links:
        self.queue.put(link)
        self.queue.task_done()
    else:
        return


def make_mal_list():
"""Open various malware and phishing related blacklists and create a list 
of URLS from which to compare to the crawled links
"""

hosts1 = "hosts.txt"
hosts2 = "MH-sitelist.txt"
hosts3 = "urls.txt"

mal_list = []

with open(hosts1) as first:
    for line1 in first:
        link = "http://" + line1.strip()
        mal_list.append(link)

with open(hosts2) as second:
    for line2 in second:
        link = "http://" + line2.strip()
        mal_list.append(link)

with open(hosts3) as third:
    for line3 in third:
        link = "http://" + line3.strip()
        mal_list.append(link)

return mal_list

def main():
    x = int(sys.argv[2])
    queue = Queue.Queue()

    mal_urls = set(make_mal_list())
    for i in xrange(THREAD_NUMBER):
        cr = Crawler(queue, mal_urls, x)
        cr.start()


   queue.put(sys.argv[1])

   queue.join()


if __name__ == '__main__':
    main()

Итак, что у меня здесь происходит, это веб-паук, который сначала создает набор из нескольких текстовых файлов, содержащих «вредоносные ссылки». Затем запускается поток, передающий как множество плохих ссылок, так и sys.argv [1]. Запущенный поток затем вызывает функцию сканирования, которая получает анализ lxml.html из sys.argv [1], а затем после анализа всех ссылок с этой начальной страницы помещает их в очередь. Цикл продолжается, и каждая ссылка, помещенная в очередь, удаляется с помощью self.queue.get (). Соответствующая ссылка затем ПРЕДЛАГАЕТСЯ сравнивать с набором плохих ссылок. Если обнаружена неправильная ссылка, предполагается, что цикл выведет ее на экран, а затем перейдет к следующей ссылке, ЕСЛИ она уже не просканировала эту ссылку.

Если это не плохо, просканируйте его, проанализируйте, поместите его ссылки в очередь и т. Д., Увеличивая счетчик при каждом сканировании ссылки и продолжая, пока счетчик не достигнет предела, определяемого значением, переданным как sys. ARGV [2]. Проблема заключается в том, что элементы, которые должны вызывать оператор if / else для 'if url not in mal_list', отсутствуют, а ссылки, помещенные в список 'crawled_already', сканируются во 2-й, 3-й и 4-й раз во всяком случае.

1 Ответ

0 голосов
/ 01 ноября 2010

Я не понимаю одну деталь этого кода: очередь помечается как task_done, если в self.queue_links найдена какая-либо новая ссылка, но, конечно, в self.crawl.Я бы подумал, что этот код будет иметь больше смысла:

def crawl(self, tgt):
    try:
        url = urlparse(tgt)
        self.crawled_links.append(tgt)
        print("\nCrawling {0}".format(tgt))
        request = urllib2.Request(tgt)
        request.add_header("User-Agent", "Mozilla/5,0")
        opener = urllib2.build_opener()
        data = opener.open(request)
        doc = parse(data).getroot()
        for tag in doc.xpath("//a[@href]"):
            old = tag.get('href')
            fixed = urllib.unquote(old)
            self.queue_links(fixed, url)
        self.queue.task_done()
    except: # TODO: write explicit exceptions the URLError, ValueERROR ...
        pass

def queue_links(self, link, url):
    if not link.startswith("#"):
        if link.startswith('/'):
            link = "http://" + url.netloc + link
        elif not link.startswith("http"):
            link = "http://" + url.netloc + "/" + link
        if link not in self.crawled_links:
            self.queue.put(link)

Не могу, однако, сказать, что у меня есть полный ответ на ваш вопрос.


Позже: документы для Queue.task_done предполагают, что task_done должно быть 1: 1 с Queue.get вызовами:

Queue.task_done () ¶

Укажите, что ранее поставленная в очередь задача выполнена.Используется потоками очереди.Для каждого get (), используемого для извлечения задачи, последующий вызов task_done () сообщает очереди, что обработка задачи завершена.

Если join () в настоящее время блокирует, оно возобновится, когда всеэлементы были обработаны (это означает, что вызов task_done () был получен для каждого элемента, который был помещен () в очередь).

Вызывает ValueError, если вызывается больше раз, чем было элементов, помещенных в очередь.

Получали ли вы [uncaught] ValueError исключения?Похоже, что это может быть так.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...