11 de ene. de 2015

Descubrir equipos en una red con ipcalc y python-nmap

En un artículo anterior se explico como descubrir equipos en una red usando ipcalc y scapy, ahora se explicará usando python-nmap.


El script pasa la red y mascara de la red que se va a analizar, se define unos puertos de los cuales se quiere saber si están abiertos y se usa la librería nmap con unos argumentos para detectar los host de la red.

A continuación el código del script:

#!/usr/bin/env python2.7
#se importa python-nmap
import nmap
#De ipcalc se importa IP y Network
from ipcalc import IP, Network
#Se crea la instancia de nmap para escanear puertos
escanear = nmap.PortScanner()
#Se define una tupla con los puertos
puertos = ("21","22","25","53","80")
#Se define los argumentos que nmap va a utilizar
argumentos = "-sS -sV -O"
#Se crea la función escaneo donde se le pasa los host y puertos.
def Escaneo(host,puertos):
    #Se hace un recorrido por puerto 
    for puerto in puertos:
        try:
            #Se verifica que el puerto esté abierto en el host
            #Si lo está se muestra, si no se continua con el siguiente puerto.
            escanear.scan(host,puerto,argumentos)
            if escanear[host]['tcp'][int(puerto)]['state'] == "open":
                print("Host: %s ,Puerto: %s, abierto" %(host,puerto))
        except KeyError:
            pass
if __name__ == "__main__":
    import sys
    try:
        #Escaneo(hosts,puertos)
       #Se recorre los host de la red, y se llama a la función escaneo que evalua que puertos están abiertos
       #en cada host.
        for x in Network('192.168.52.0/24'):
            host =str(x)
            Escaneo(host,puertos)
    except KeyboardInterrupt:
        sys.exit()

El resultado de ejecutar el script es el siguiente:

Host: 192.168.52.2 ,Puerto: 22, abierto
Host: 192.168.52.2 ,Puerto: 53, abierto
Host: 192.168.52.9 ,Puerto: 22, abierto
Host: 192.168.52.9 ,Puerto: 53, abierto
Host: 192.168.52.17 ,Puerto: 22, abierto
Host: 192.168.52.17 ,Puerto: 53, abierto
Host: 192.168.52.33 ,Puerto: 22, abierto
Host: 192.168.52.33 ,Puerto: 53, abierto
Host: 192.168.52.65 ,Puerto: 22, abierto
Host: 192.168.52.65 ,Puerto: 53, abierto
...


Generación de un histograma de frecuencia con numpy, Scipy y Matplotlib

En el artículo de creación de grafos se muestra como generar un histograma, ahora se mostrará un histograma con datos generados.

Se generarán datos de manera aleatoria, y con ella se generará el histograma con la función scipy.stats.histogram, luego se gráfica el histograma.

A continuación el código del programa:


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#Se importa numpy como np
import numpy as np
import matplotlib.pyplot as plt
import scipy.stats as st
#Se importa pylab
from pylab import *
#Generación de números aleatorios menores que 1000
x = np.random.randn(1000)
#Generación de los datos del histograma con scipy.stats.
n, low_range, binsize, extrapoints = st.histogram(x)
#define el rango superior
upper_range = low_range+binsize*(len(n)-1)
#Se calcula los intervalos discretos
bins = np.linspace(low_range, upper_range, len(n))
#Generación del gráfico de barras
bar(bins, n, width=0.3, color='blue')
#Etiquetas de los ejes X y Y.
xlabel('X', fontsize=15)
ylabel('número de datos discretos', fontsize=15)
#Se muestra la gráfica.
show()
A continuación se muestra la gráfica:

Gráfica de presión de vapor con numpy y matplotlib

Retomando los artículos de numpy y matplotlib, en este caso se mostrará una gráfica del cálculo del vapor de agua entre -100 a 100 grados centigrados.

La ecuación de vapor es la siguiente:

Donde es está en pascal, T en grados centigrados.


A continuación se muestra el código para generar la gráfica:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#Se importa numpy como np
import numpy as np
#Se importa xlabel, ylabel, plot y show de pylab
from pylab import xlabel,ylabel, plot, show
#Se define el rango de la temperatura, de -100 a 100 con
#incrementos de 50.
T = np.linspace(-100,100,50)
#Se realiza el cálculo de la presión pasandole el arreglo de valores de
#la temperatura
es = 611*np.exp(17.27*T/(237.3+T))
#Se crea la gráfica
plot(T,es)
#Se define las etiquetas de los ejes X y Y.
xlabel('T (Grados centigrados)')
ylabel(u'Presión de vapor (Pa)')
#Se muestra la gráfica
show()
La gráfica se muestra a continuación:

2 de ene. de 2015

Extracción de datos de páginas web con scrapy y MongoDB

En el artículo anterior (Extracción de datos de páginas web con scrapy) se hizo una introducción del uso de scrapy basandose e el tutorial de la página del proyecto.

Este artículo continua la serie de artículos sobre extracción de datos de páginas web (webscraping).

En el artículo anterior se extrajo información de la página dmoz.org, en este caso se usará la misma página, pero está vez basandose en el artículo en Inglés Web scraping with scrapy and MongoDB. En este artículo le hacen la extracción de datos a stackoverflow, pero por problemas de conexión se mostrará la extracción con el sitio dmoz.org.

Aparte de hacer la extracción de datos se agregará lo extraído a la basa de datos Mongo, para montar el servidor MongoDB pueden seguir el siguiente artículo, y para usarlo desde python este otro.

Para visualizar los datos insertados en MongoDB se puede instalar la aplicación robomongo.

El procedimiento es el mismo que el del artículo anterior, se crea el proyecto:
$scrapy startproject dmoz

Se modifica el archivo dmoz/dmoz/items.py:
from scrapy import Item,Field

class DmozItem(Item):
    title = Field()
    link = Field()
    desc = Field()


Ahora se crea la araña (dmoz/dmoz/spider/dmoz_spider.py):

# -*- coding: utf-8 -*-
#Se importa Spider y Selector
from scrapy import Spider
from scrapy.selector import Selector

#Se importa la clase DmozItem
from dmoz.items import DmozItem


#Se crea la clase DmozSpider que hereda de Spider .
class DmozSpider(Spider):
    #Se define el nombre del proyecto
    name = 'dmoz'
    #El proyecto al cual está permitido
    allowed_domains = ['dmoz.org']
    #Se define las urls a extraer datos
    start_urls = ["http://www.dmoz.org/Computers/Programming/Languages/Python/Books/",
        "http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/"
    ]


    def parse(self, response):
        #Se instancia el selector de ul-> li del artículo anterior
        questions = Selector(response).xpath('//ul/li')
        #Se crea una lista de items
        items = []
        
        #Se recorre los li
        for question in questions:
            #Se instancia DmozItem en item
            item = DmozItem()
            #Se extra title, link y descripción de cada enlace de la página
            title = question.xpath('a/text()').extract()
            link = question.xpath('a/@href').extract()
            desc = question.xpath('text()').extract()
            #Se asocia estos elementos a la lista
            item['title'] = title
            item['link'] = link
            item['desc'] = desc
            items.append(item)
        #Se retorna el item
        return item



Se prueba la araña y luego se guarda en un archivo json.
scrapy crawl dmoz

2015-01-02 14:33:37-0430 [scrapy] INFO: Scrapy 0.24.2 started (bot: dmoz)
2015-01-02 14:33:37-0430 [scrapy] INFO: Optional features available: ssl, http11, boto, django
2015-01-02 14:33:37-0430 [scrapy] INFO: Overridden settings: {'NEWSPIDER_MODULE': 'dmoz.spiders', 'SPIDER_MODULES': ['dmoz.spiders'], 'BOT_NAME': 'dmoz'}
2015-01-02 14:33:37-0430 [scrapy] INFO: Enabled extensions: LogStats, TelnetConsole, CloseSpider, WebService, CoreStats, SpiderState
2015-01-02 14:33:39-0430 [scrapy] INFO: Enabled downloader middlewares: HttpAuthMiddleware, DownloadTimeoutMiddleware, UserAgentMiddleware, RetryMiddleware, DefaultHeadersMiddleware, MetaRefreshMiddleware, HttpCompressionMiddleware, RedirectMiddleware, CookiesMiddleware, ChunkedTransferMiddleware, DownloaderStats
2015-01-02 14:33:39-0430 [scrapy] INFO: Enabled spider middlewares: HttpErrorMiddleware, OffsiteMiddleware, RefererMiddleware, UrlLengthMiddleware, DepthMiddleware
/usr/lib/python2.7/dist-packages/scrapy/contrib/pipeline/__init__.py:21: ScrapyDeprecationWarning: ITEM_PIPELINES defined as a list or a set is deprecated, switch to a dict
  category=ScrapyDeprecationWarning, stacklevel=1)
2015-01-02 14:33:39-0430 [scrapy] INFO: Enabled item pipelines: MongoDBPipeline
2015-01-02 14:33:39-0430 [dmoz] INFO: Spider opened
2015-01-02 14:33:39-0430 [dmoz] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min)
2015-01-02 14:33:39-0430 [scrapy] DEBUG: Telnet console listening on 127.0.0.1:6023
2015-01-02 14:33:39-0430 [scrapy] DEBUG: Web service listening on 127.0.0.1:6080
2015-01-02 14:33:45-0430 [dmoz] DEBUG: Crawled (200) <GET http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/> (referer: None)
2015-01-02 14:33:45-0430 [dmoz] DEBUG: Question added to MongoDB database!
2015-01-02 14:33:45-0430 [dmoz] DEBUG: Scraped from <200 http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/>
{'desc': [u'\r\n\t\r\n                                ',
         u' \r\n\t\t\t\r\n                                - Scripts, examples and news about Python programming for the Windows platform.\r\n                                \r\n                                ',
         u'\r\n                                '],
'link': [u'http://win32com.goermezer.de/'],
'title': [u'Social Bug']}
2015-01-02 14:33:46-0430 [dmoz] DEBUG: Crawled (200) <GET http://www.dmoz.org/Computers/Programming/Languages/Python/Books/> (referer: None)
2015-01-02 14:33:46-0430 [dmoz] DEBUG: Question added to MongoDB database!
2015-01-02 14:33:46-0430 [dmoz] DEBUG: Scraped from <200 http://www.dmoz.org/Computers/Programming/Languages/Python/Books/>
{'desc': [u'\r\n\t\r\n                                ',
         u' \r\n\t\t\t\r\n                                - By Sean McGrath; Prentice Hall PTR, 2000, ISBN 0130211192, has CD-ROM. Methods to build XML applications fast, Python tutorial, DOM and SAX, new Pyxie open source XML processing library. [Prentice Hall PTR]\r\n                                \r\n                                ',
         u'\r\n                                '],
'link': [u'http://www.informit.com/store/product.aspx?isbn=0130211192'],
'title': [u'XML Processing with Python']}
2015-01-02 14:33:46-0430 [dmoz] INFO: Closing spider (finished)
2015-01-02 14:33:46-0430 [dmoz] INFO: Dumping Scrapy stats:
{'downloader/request_bytes': 516,
'downloader/request_count': 2,
'downloader/request_method_count/GET': 2,
'downloader/response_bytes': 16342,
'downloader/response_count': 2,
'downloader/response_status_count/200': 2,
'finish_reason': 'finished',
'finish_time': datetime.datetime(2015, 1, 2, 19, 3, 46, 119507),
'item_scraped_count': 2,
'log_count/DEBUG': 8,
'log_count/INFO': 7,
'response_received_count': 2,
'scheduler/dequeued': 2,
'scheduler/dequeued/memory': 2,
'scheduler/enqueued': 2,
'scheduler/enqueued/memory': 2,
'start_time': datetime.datetime(2015, 1, 2, 19, 3, 39, 404138)}
2015-01-02 14:33:46-0430 [dmoz] INFO: Spider closed (finished)



Se guarda la información en el archivo json:
scrapy crawl dmoz -o dmoz.json -t json

El archivo dmoz.json contiene lo siguiente:
[{"desc": ["\r\n\t\r\n                                ", " \r\n\t\t\t\r\n                                - Scripts, examples and news about Python programming for the Windows platform.\r\n                                \r\n                                ", "\r\n                                "], "link": ["http://win32com.goermezer.de/"], "title": ["Social Bug"]},
{"desc": ["\r\n\t\r\n                                ", " \r\n\t\t\t\r\n                                - By Sean McGrath; Prentice Hall PTR, 2000, ISBN 0130211192, has CD-ROM. Methods to build XML applications fast, Python tutorial, DOM and SAX, new Pyxie open source XML processing library. [Prentice Hall PTR]\r\n                                \r\n                                ", "\r\n                                "], "link": ["http://www.informit.com/store/product.aspx?isbn=0130211192"], "

Para configurar el acceso a MongoDB se edita el archivo dmoz/dmoz/settings.py, se agrega lo siguiente:
ITEM_PIPELINES = ['dmoz.pipelines.MongoDBPipeline', ]

#información de conexión con el servidor mongodb, host, puerto, base de datos y colección.
MONGODB_SERVER = "localhost"
MONGODB_PORT = 27017
MONGODB_DB = "dmoz"
MONGODB_COLLECTION = "links"

Se edita dmoz/dmoz/pipelines.py para generar el flujo del proceso de extracción de datos, se define la conexión a la base de datos y luego se inserta los datos a mongodb:

#Se importa pymongo
import pymongo

#Se importa la configuración de settings
from scrapy.conf import settings

#Se importa DropItem y log
from scrapy.exceptions import DropItem
from scrapy import log


#Se crea la clase MongoDBPipeline
class MongoDBPipeline(object):

    def __init__(self):
        #Se conecta al servidor mongodb
        connection = pymongo.Connection(
            settings['MONGODB_SERVER'],
            settings['MONGODB_PORT']
        )
        #Se instancia los datos de conexión y la colección de los datos
        db = connection[settings['MONGODB_DB']]
        self.collection = db[settings['MONGODB_COLLECTION']]

    #Se procesa los items
    def process_item(self, item, spider):
        valid = True
        #Se recorre los datos si no hay datos se descarta, si los hay se inserta y se agrega un mensaje al log.
        for data in item:
            if not data:
                valid = False
                raise DropItem("Missing {0}!".format(data))
        if valid:
            self.collection.insert(dict(item))
            log.msg("Question added to MongoDB database!",
                    level=log.DEBUG, spider=spider)
        return item



Se vuelve a probar la extracción de datos:
scrapy crawl dmoz

Desde el shell se ejecuta el cliente de mongo:
mongo
MongoDB shell version: 2.4.10
connecting to: test
>

Se muestra las base de datos existentes:
> show dbs
dmoz 0.203125GB
local 0.078125GB

Se usa la base de datos dmoz:
> use dmoz
switched to db dmoz

Se muestra las colecciones existentes de la base de datos:
> show collections
links
system.indexes

Se muestra el contenido de la colección links:
> db.links.find()
{ "_id" : ObjectId("54a6ef962b405e3dc6fd96b8"), "title" : [  "XML Processing with Python" ], "link" : [  "http://www.informit.com/store/product.aspx?isbn=0130211192" ], "desc" : [ "\r\n\t\r\n                                ", " \r\n\t\t\t\r\n                                - By Sean McGrath; Prentice Hall PTR, 2000, ISBN 0130211192, has CD-ROM. Methods to build XML applications fast, Python tutorial, DOM and SAX, new Pyxie open source XML processing library. [Prentice Hall PTR]\r\n                                \r\n                                ", "\r\n                                " ] }
{ "_id" : ObjectId("54a6ef962b405e3dc6fd96b9"), "title" : [  "Social Bug" ], "link" : [  "http://win32com.goermezer.de/" ], "desc" : [ "\r\n\t\r\n                                ", " \r\n\t\t\t\r\n                                - Scripts, examples and news about Python programming for the Windows platform.\r\n                                \r\n                                ", "\r\n                                " ] }

Para finalizar se muestra la captura de pantalla de la aplicación robomongo que muestra el mismo contenido de la colección links:

AddThis