Кто-нибудь знает хороший веб-сканер на Python, который я мог бы использовать?

Вопрос задан: 11 лет назад Последняя активность: 8 лет назад
up 67 down

Я наполовину испытывал желание написать свой собственный, но у меня действительно не хватает времени прямо сейчас. Я видел список Википедии сканеры с открытым исходным кодом но я бы предпочел что-то написанное на Python. Я понимаю, что я мог бы просто использовать один из инструментов на странице Википедии и обернуть его в Python. Я мог бы закончить тем, что сделал это - если у кого-нибудь есть какой-либо совет относительно любого из тех инструментов, я открыт для слушания о них Я использовал Heritrix через его веб-интерфейс и нашел его довольно громоздким. Я определенно не буду использовать браузер API для моего будущего проекта.

Заранее спасибо. Кроме того, это мой первый ТАК вопрос!

8 ответов

Возможно, для Вашего проекта будут необходимы бесплатные векторные карты. На нашем сайте представлены карты для всех стран.

Реклама

up 56 down accepted
  • Механизировать мой любимый; отличные возможности просмотра на высоком уровне (очень простое заполнение и отправка форм).
  • Twill это простой язык сценариев, построенный на основе Mechanize
  • BeautifulSoup + urllib2 также работает довольно хорошо.
  • Scrapy выглядит как чрезвычайно перспективный проект; это новое.
up 44 down

использование Scrapy.

Это основанный на витой основе механизм сканирования веб-страниц. Все еще в стадии разработки, но это уже работает. Имеет много вкусностей:

  • Встроенная поддержка парсинга HTML, XML, CSV и Javascript
  • Медиа-конвейер для очистки объектов с изображениями (или любых других носителей) и загрузки файлов изображений.
  • Поддержка расширения Scrapy путем подключения вашей собственной функциональности с использованием промежуточного программного обеспечения, расширений и конвейеров.
  • Широкий спектр встроенных промежуточных программ и расширений для обработки сжатия, кэша, файлов cookie, проверки подлинности, подмены пользовательских агентов, обработки robots.txt, статистики, ограничения глубины сканирования и т.д.
  • Интерактивная консольная оболочка, очень полезная для разработки и отладки
  • Веб-консоль управления для мониторинга и контроля вашего бота
  • Консоль Telnet для низкоуровневого доступа к процессу Scrapy

Пример кода для извлечения информации обо всех торрент-файлах, добавленных сегодня в mininova торрент-сайт, с помощью селектора XPath в HTML возвращается:

class Torrent(ScrapedItem):
    pass

class MininovaSpider(CrawlSpider):
    domain_name = 'mininova.org'
    start_urls = ['http://www.mininova.org/today']
    rules = [Rule(RegexLinkExtractor(allow=['/tor/\d+']), 'parse_torrent')]

    def parse_torrent(self, response):
        x = HtmlXPathSelector(response)
        torrent = Torrent()

        torrent.url = response.url
        torrent.name = x.x("//h1/text()").extract()
        torrent.description = x.x("//div[@id='description']").extract()
        torrent.size = x.x("//div[@id='info-left']/p[2]/text()[2]").extract()
        return [torrent]
up 6 down

Проверить сенокосец, многопоточный веб-сканер, написанный на Python, также рассмотрим spider.py модуль.

А также вот вы можете найти примеры кода для создания простого веб-сканера.

up 3 down

Я взломал вышеупомянутый скрипт, чтобы включить страницу входа в систему, так как мне это было нужно для доступа к сайту drupal. Не красиво, но может помочь кому-то там.

#!/usr/bin/python

import httplib2
import urllib
import urllib2
from cookielib import CookieJar
import sys
import re
from HTMLParser import HTMLParser

class miniHTMLParser( HTMLParser ):

  viewedQueue = []
  instQueue = []
  headers = {}
  opener = ""

  def get_next_link( self ):
    if self.instQueue == []:
      return ''
    else:
      return self.instQueue.pop(0)


  def gethtmlfile( self, site, page ):
    try:
        url = 'http://'+site+''+page
        response = self.opener.open(url)
        return response.read()
    except Exception, err:
        print " Error retrieving: "+page
        sys.stderr.write('ERROR: %s\n' % str(err))
    return "" 

    return resppage

  def loginSite( self, site_url ):
    try:
    cj = CookieJar()
    self.opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))

    url = 'http://'+site_url 
        params = {'name': 'customer_admin', 'pass': 'customer_admin123', 'opt': 'Log in', 'form_build_id': 'form-3560fb42948a06b01d063de48aa216ab', 'form_id':'user_login_block'}
    user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
    self.headers = { 'User-Agent' : user_agent }

    data = urllib.urlencode(params)
    response = self.opener.open(url, data)
    print "Logged in"
    return response.read() 

    except Exception, err:
    print " Error logging in"
    sys.stderr.write('ERROR: %s\n' % str(err))

    return 1

  def handle_starttag( self, tag, attrs ):
    if tag == 'a':
      newstr = str(attrs[0][1])
      print newstr
      if re.search('http', newstr) == None:
        if re.search('mailto', newstr) == None:
          if re.search('#', newstr) == None:
            if (newstr in self.viewedQueue) == False:
              print "  adding", newstr
              self.instQueue.append( newstr )
              self.viewedQueue.append( newstr )
          else:
            print "  ignoring", newstr
        else:
          print "  ignoring", newstr
      else:
        print "  ignoring", newstr


def main():

  if len(sys.argv)!=3:
    print "usage is ./minispider.py site link"
    sys.exit(2)

  mySpider = miniHTMLParser()

  site = sys.argv[1]
  link = sys.argv[2]

  url_login_link = site+"/node?destination=node"
  print "\nLogging in", url_login_link
  x = mySpider.loginSite( url_login_link )

  while link != '':

    print "\nChecking link ", link

    # Get the file from the site and link
    retfile = mySpider.gethtmlfile( site, link )

    # Feed the file into the HTML parser
    mySpider.feed(retfile)

    # Search the retfile here

    # Get the next link in level traversal order
    link = mySpider.get_next_link()

  mySpider.close()

  print "\ndone\n"

if __name__ == "__main__":
  main()
up 3 down

Я использовал Ruya и нашел это довольно хорошо.

up 3 down

Поверь мне, нет ничего лучше скручивания... следующий код может сканировать 10000 URL-адресов параллельно менее чем за 300 секунд в Amazon EC2

ПРЕДУПРЕЖДЕНИЕ. Не используйте один и тот же домен на такой высокой скорости...

#! /usr/bin/env python
# -*- coding: iso-8859-1 -*-
# vi:ts=4:et
# $Id: retriever-multi.py,v 1.29 2005/07/28 11:04:13 mfx Exp $

#
# Usage: python retriever-multi.py <file with URLs to fetch> [<# of
#          concurrent connections>]
#

import sys
import pycurl

# We should ignore SIGPIPE when using pycurl.NOSIGNAL - see
# the libcurl tutorial for more info.
try:
    import signal
    from signal import SIGPIPE, SIG_IGN
    signal.signal(signal.SIGPIPE, signal.SIG_IGN)
except ImportError:
    pass


# Get args
num_conn = 10
try:
    if sys.argv[1] == "-":
        urls = sys.stdin.readlines()
    else:
        urls = open(sys.argv[1]).readlines()
    if len(sys.argv) >= 3:
        num_conn = int(sys.argv[2])
except:
    print "Usage: %s <file with URLs to fetch> [<# of concurrent connections>]" % sys.argv[0]
    raise SystemExit


# Make a queue with (url, filename) tuples
queue = []
for url in urls:
    url = url.strip()
    if not url or url[0] == "#":
        continue
    filename = "doc_%03d.dat" % (len(queue) + 1)
    queue.append((url, filename))


# Check args
assert queue, "no URLs given"
num_urls = len(queue)
num_conn = min(num_conn, num_urls)
assert 1 <= num_conn <= 10000, "invalid number of concurrent connections"
print "PycURL %s (compiled against 0x%x)" % (pycurl.version, pycurl.COMPILE_LIBCURL_VERSION_NUM)
print "----- Getting", num_urls, "URLs using", num_conn, "connections -----"


# Pre-allocate a list of curl objects
m = pycurl.CurlMulti()
m.handles = []
for i in range(num_conn):
    c = pycurl.Curl()
    c.fp = None
    c.setopt(pycurl.FOLLOWLOCATION, 1)
    c.setopt(pycurl.MAXREDIRS, 5)
    c.setopt(pycurl.CONNECTTIMEOUT, 30)
    c.setopt(pycurl.TIMEOUT, 300)
    c.setopt(pycurl.NOSIGNAL, 1)
    m.handles.append(c)


# Main loop
freelist = m.handles[:]
num_processed = 0
while num_processed < num_urls:
    # If there is an url to process and a free curl object, add to multi stack
    while queue and freelist:
        url, filename = queue.pop(0)
        c = freelist.pop()
        c.fp = open(filename, "wb")
        c.setopt(pycurl.URL, url)
        c.setopt(pycurl.WRITEDATA, c.fp)
        m.add_handle(c)
        # store some info
        c.filename = filename
        c.url = url
    # Run the internal curl state machine for the multi stack
    while 1:
        ret, num_handles = m.perform()
        if ret != pycurl.E_CALL_MULTI_PERFORM:
            break
    # Check for curl objects which have terminated, and add them to the freelist
    while 1:
        num_q, ok_list, err_list = m.info_read()
        for c in ok_list:
            c.fp.close()
            c.fp = None
            m.remove_handle(c)
            print "Success:", c.filename, c.url, c.getinfo(pycurl.EFFECTIVE_URL)
            freelist.append(c)
        for c, errno, errmsg in err_list:
            c.fp.close()
            c.fp = None
            m.remove_handle(c)
            print "Failed: ", c.filename, c.url, errno, errmsg
            freelist.append(c)
        num_processed = num_processed + len(ok_list) + len(err_list)
        if num_q == 0:
            break
    # Currently no more I/O is pending, could do something in the meantime
    # (display a progress bar, etc.).
    # We just call select() to sleep until some more data is available.
    m.select(1.0)


# Cleanup
for c in m.handles:
    if c.fp is not None:
        c.fp.close()
        c.fp = None
    c.close()
m.close()
up 2 down

Другая простой паук Использует BeautifulSoup и urllib2. Ничего сложного, просто читает все, что делает HREF, создает список и проходит через него.

up 0 down

pyspider.py