Taller de web scrapping, consumo de apis, etc

Iniciado por seth, Agosto 25, 2016, 11:01:13 PM

Tema anterior - Siguiente tema

0 Miembros y 1 Visitante están viendo este tema.

Agosto 25, 2016, 11:01:13 PM Ultima modificación: Agosto 29, 2016, 09:10:15 PM por seth
Edit: Hola. Esto es un taller sobre sacar datos de webs, hacer bots, pegarle a apis y ese tipo de cosas.
La idea es que lo vayan siguiendo y haciendo los ejercicios para afirmar los conocimientos. Cuando ande lo que hicieron, posteenlo. Si tienen dudas, poteenlas aca mismo.

Indice:
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

Abajo el mensaje original


Hola gente, tengo ganas de hacer un taller. La idea es hacer un post cada tanto en el que explico algo y dejar unos dias para que hagan ejercicios y suban los resultados. Para que funcione eso tiene que haber gente que lo quiera hacer mientras van saliendo los posts

Podemos hacer otro tema, pero estaba pensando en hacer algo asi:
Scrapping de webs (el ejercicio es sacar datos del foro)
Lo mismo pero mandando post (el ejercicio es tratar de loguearse con distintas cuentas que vayamos sacando con lo del post anterior)
Algo similar pero con una web que muestre los datos con javascript
Una explicacion de apis rest y usamos alguna
Capaz algo asi con soap y oauth
Y para terminar, hacemos un bot para alguna web

Quien se anota?
Hay que saber programar y un poco de python (variables, for, while, if, funciones, import y poco mas)

Que bien @No tienes permitido ver los links. Registrarse o Entrar a mi cuenta! Yo me apunto. Se ve bastante interesante la propuesta.
Decime que necesitas para que arranquemos.

Saludos!
ANTRAX


Estoy aprendiendo de a poco y no sabria como hacerlo, pero me suscribo como espectador, exitos con el taler.

Dale nomas, todo lo que sea para aportar bienvenido. Si necesitas una mano tan solo avisa.

Saludos.
Security Researcher
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

Agosto 29, 2016, 09:00:27 PM #4 Ultima modificación: Agosto 29, 2016, 09:16:31 PM por seth
Bueno, no se por que esto está en off topic, pero arrancamos con el primer post (el que puede lo manda a python? o capaz talleres underc0de, donde corresponda)

Vamos a usar python 2.7
Para hacer peticiones http vamos a usar la libreria requests. Es facil de usar y tiene buena documentacion (leanla cuando quieran hacer algo que no expliqué): No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Cuando vean codigo corranlo, no se queden con lo que yo les digo que hace. Tambien puede ser util y modificandolo para ver que pasa.

Todos saben que es http, no? Es el protocolo que se usa en las webs. https es http cifrado y para nuestro uso va a ser exactamente lo mismo porque eso lo maneja la libreria.
Cada vez que abris una web, el navegador se conecta al servidor y le hace una peticion. Cada vez que mandas un formulario, lo mismo. También cuando carga css, imagenes, javascript, etc. (si, se pueden reusar conexiones pero queda afuera de esto que voy a explicar).
La mayoria de estas peticiones son del tipo GET. En las peticiones get, todos los parametros se pasan en la url. A veces, cuando mandas un formulario se usa POST en lugar de GET. En POST, podes mandar datos que no van por la url, van por otro lado, y por lo tanto pueden ser mas grandes.
Hay mas métodos que no se suelen usar en webs.

Hagamos un get al index del foro:
Código: python
import requests #importa la libreria requests

resultado = requests.get("https://underc0de.org/foro/index.php") #dentro del modulo requests, busca la funcion get
print resultado.text #el resultado es un objeto con varios metodos y propiedades, por ahora usamos .text

Como se hacer eso? está en el link que pasé de la libreria
Si da un error de la libreria requests, hay que instalarla con pip install requests

Eso nos va a imprimir el html del indice del foro. Esto del web scrapping se trata de sacar datos, asi que vamos a tratar de sacar la cantidad de usuarios en linea. Nos importa buscar donde está ese dato y que tiene alrededor, como para poder hacer que el programa lo identifique:
Código: html5
			<p class="inline stats">
1738 Visitantes, 209 Usuarios (16 Arañas, 2 Oculto(s))
</p>


Quiero sacar ese 209, que va a ir cambiando, y mostrarlo con el programa.
Hay varias formas de sacar eso. Nosotros no vamos a tratar de parsear el html, si no que vamos a hacerlo de una forma un poco mas bruta, con expresiones regulares. Vieron cuando en un buscador podes poner * y ? para que hagan de comodines? las expresiones regulares son algo asi, pero muchisimo mas potentes.
En python hay que usar el modulo re:
Código: python
import re

Documentacion:
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

Se usa asi:
Cita de: pythonNo tienes permitido ver los links. Registrarse o Entrar a mi cuenta("regexp", "string")
Donde regexp es la expresion regular y string es el texto en el que va a buscar (en nuestro caso, resultado.text)
Por ejemplo:
Código: python
import re
print re.search("planeta", "hola mundo")
print re.search("mundo", "hola mundo")

El primer print va a devolver None, porque no encontró "planeta" en "hola mundo" y el segundo va a devolver un objeto del tipo SRE_Match. Esto nos permite hacer un if:
Código: python
import requests
import re

resultado = requests.get("https://underc0de.org/foro/index.php")


if re.search("underc0de", resultado.text):
    print "se encontro underc0de en el html del index"
else:
    print "no se encontro underc0de en el html del index"


if re.search("elefante", resultado.text):
    print "se encontro elefante en el html del index"
else:
    print "no se encontro elefante en el html del index"


Hasta ahi es lo mismo que las funciones de busqueda en cadenas, pero podemos usar muchos caracteres que en una expresion regular tienen un significado especial.
Por ejemplo, un . va a ser un comodin que matchea con cualquier caracter:
Código: python
import re

regexp = "unde.c0de"
texto = "underc0de"
if re.search(regexp, texto):
    print texto + " matchea con " + regexp
else:
    print texto + " NO matchea con " + regexp

eso va a entrar por el true
Si quiero que el . sea interpretado como un . literal, hay que escaparlo asi: \.
Reemplazando en el ejemplo anterior las variables por esto, no va a matchear:
Código: python
regexp = "unde\.c0de"
texto = "underc0de"

Pero asi si:
Código: python
regexp = "unde\.c0de"
texto = "unde.c0de"


Con un * va a matchear el caracter anterior entre 0 e infinitas veces. Ejemplos:
Código: python
regexp = "under*c0de"
texto = "underc0de"

Código: python
regexp = "under*c0de"
texto = "underrrc0de"

Código: python
regexp = "under*c0de"
texto = "undec0de"

Los tres matchean. También podemos combinar eso con un ., que matchearia casi cualquier cosa:
Código: python

regexp = ".*"
texto = "underc0de"


Esto no nos está alcanzando, porque nosotros queremos extraer datos. Esto se hace envolviendo en parentesis la parte que va a matchear con los datos que queremos. Para ver que es lo que matchearon los parentesis, usamos el metodo .groups() del objeto que nos devuelve .search():
Código: python

import re

resultado = re.search("un(.*)de", "underc0de")
print resultado.groups()

El resultado:
Código: php
('derc0',)

Eso es una tupla, que en este caso tiene un solo resultado. Tambien pueden haber dos:
Código: python

import re

resultado = re.search("u(.*)r(.*)e", "underc0de")
print resultado.groups()

Resultado:
Código: php
('nde', 'c0d')


Vamos con otro caso:
Código: python
import re

resultado = re.search("und(.*)de", "underc0de underc0de")
print resultado.groups()


Que va a devolver? "erc0" o "erc0de underc0"? Resulta que el * va a matchear todo lo que pueda, asi que devuelve algo que probablemente no sea lo que buscamos:
Código: php
('derc0de underc0',)
Para que matchee lo minimo posible hay que agregarle un ?:
Código: python
import re

resultado = re.search("und(.*?)de", "underc0de underc0de")
print resultado.groups()


Esto es muy util, por ejemplo, si tenemos un html asi:
Código: html5
<div id="sidebar"><div id="dato_que_queremos">EL DATO ACA</div></div>

La expresion regular que queremos es esta:
Código: php
<div id="dato_que_queremos">(.*?)</div>

Sin el ? tambien va a traer el </div>

Para acceder a cada dato particular podemos usar .group(ID+1), donde ID es el indice de la tupla. Hay que sumarle 1 porque .group(0) devuelve todo lo que matcheo, no solo lo que va entre parentesis.
Volvamos a lo de sacar el 209 de aca:
Código: html5
<p class="inline stats">
1738 Visitantes, 209 Usuarios (16 Arañas, 2 Oculto(s))
</p>


La expresion regular puede ser esta:
Código: php
Visitantes, (.*?) Usuarios


Y el codigo nos quedaria asi:
Código: python

import requests
import re

web = requests.get("https://underc0de.org/foro/index.php")
regexp = 'Visitantes, (.*?) Usuarios'
resultado = re.search(regexp, web.text)
print resultado.group(1)

Eso nos imprime la cantidad de usuarios conectados

Ahora quiero sacar la lista de los ultimos mensajes publicados, esa que sale abajo. El html es asi:
Código: html5

<dl id="ic_recentposts" class="middletext">
<dt><strong><a href="https://underc0de.org/foro/dudas-generales-121/la-ram/msg104688/?topicseen#msg104688" rel="nofollow">Re:Ocupar la memoria RAM de procesos inutiles</a></strong> por <a href="https://underc0de.org/foro/profile/selohu/">selohu</a> (<a href="https://underc0de.org/foro/dudas-generales-121/">Dudas y pedidos generales</a>)</dt>
<dd><strong>Hoy</strong> a las 07:14:59 pm</dd>
<dt><strong><a href="https://underc0de.org/foro/dudas-generales-121/kali-payload-y-no-ip-ataque-fuera-lan/msg104687/?topicseen#msg104687" rel="nofollow">Re:kali payload y no-ip ataque fuera lan</a></strong> por <a href="https://underc0de.org/foro/profile/blackdrake/">blackdrake</a> (<a href="https://underc0de.org/foro/dudas-generales-121/">Dudas y pedidos generales</a>)</dt>
<dd><strong>Hoy</strong> a las 07:11:33 pm</dd>
<dt><strong><a href="https://underc0de.org/foro/dudas-generales-121/android-duda-base-de-datos/msg104686/?topicseen#msg104686" rel="nofollow">Re:Android -  Duda Base de Datos para camareros en un bar</a></strong> por <a href="https://underc0de.org/foro/profile/seth/">seth</a> (<a href="https://underc0de.org/foro/dudas-generales-121/">Dudas y pedidos generales</a>)</dt>
<dd><strong>Hoy</strong> a las 07:10:00 pm</dd>
<dt><strong><a href="https://underc0de.org/foro/dudas-generales-121/dudas-sin-aclarar/msg104685/?topicseen#msg104685" rel="nofollow">Re:Empezar en las ramas de Phishing y Programación</a></strong> por <a href="https://underc0de.org/foro/profile/blackdrake/">blackdrake</a> (<a href="https://underc0de.org/foro/dudas-generales-121/">Dudas y pedidos generales</a>)</dt>
<dd><strong>Hoy</strong> a las 07:08:29 pm</dd>
<dt><strong><a href="https://underc0de.org/foro/dudas-generales-121/stub-limpio-server-detectado-por-que/msg104684/?topicseen#msg104684" rel="nofollow">Re:stub limpio server detectado, por que?</a></strong> por <a href="https://underc0de.org/foro/profile/blackdrake/">blackdrake</a> (<a href="https://underc0de.org/foro/dudas-generales-121/">Dudas y pedidos generales</a>)</dt>
<dd><strong>Hoy</strong> a las 07:06:05 pm</dd>
<dt><strong><a href="https://underc0de.org/foro/dudas-generales-121/symlink/msg104683/?topicseen#msg104683" rel="nofollow">Re:Symlink</a></strong> por <a href="https://underc0de.org/foro/profile/blackdrake/">blackdrake</a> (<a href="https://underc0de.org/foro/dudas-generales-121/">Dudas y pedidos generales</a>)</dt>
<dd><strong>Hoy</strong> a las 07:03:10 pm</dd>
<dt><strong><a href="https://underc0de.org/foro/dudas-generales-121/que-me-aconsejan-en-ventiladores-y-muestras-de-mis-datos/msg104682/?topicseen#msg104682" rel="nofollow">Re:Que me aconsejan en ventiladores y muestras de mis datos.</a></strong> por <a href="https://underc0de.org/foro/profile/selohu/">selohu</a> (<a href="https://underc0de.org/foro/dudas-generales-121/">Dudas y pedidos generales</a>)</dt>
<dd><strong>Hoy</strong> a las 06:35:01 pm</dd>
</dl>


La complicacion es que queremos matchear varios posts con una sola regexp, para eso vamos a usar re.findall():
Código: python

import requests
import re

web = requests.get("https://underc0de.org/foro/index.php")
regexp = '<dt><strong><a href=".*?" rel="nofollow">(.*?)</a></strong>'
resultado = re.findall(regexp, web.text)
print resultado

Presten atencion a que usamos .*? para que matchee con cualquier url, pero no nos interesa capturarlas.
Nos va a imprimir una lista. Cada elemento de esa lista es uno de los matches:
Código: php
[u'Re:[Ayuda] Window no se monta en el grub (est\xe1 cifrado)', u'Re:Saber ID De Un objeto JQuery ?', u'Re:Ocupar la memoria RAM de procesos inutiles', u'Re:kali payload y no-ip ataque fuera lan', u'Re:Android -  Duda Base de Datos para camareros en un bar', u'Re:Empezar en las ramas de Phishing y Programaci\xf3n', u'Re:stub limpio server detectado, por que?']


Ahora, si agregamos parentesis para capturar las urls nos va a devolver una lista de tuplas, donde cada tupla tiene la url y el titulo del post:
Código: python
import requests
import re

web = requests.get("https://underc0de.org/foro/index.php")
regexp = '<dt><strong><a href="(.*?)" rel="nofollow">(.*?)</a></strong>'
resultado = re.findall(regexp, web.text)
print resultado

Código: php
[(u'https://underc0de.org/foro/dudas-generales-121/(ayuda)-window-no-se-monta-en-el-grub-(-esta-cifrado)/msg104690/?topicseen;PHPSESSID=ub91qif2cdbng1itkjomd0g646#msg104690', u'Re:[Ayuda] Window no se monta en el grub (est\xe1 cifrado)'), (u'https://underc0de.org/foro/dudas-generales-121/saber-id-de-un-objeto-jquery/msg104689/?topicseen;PHPSESSID=ub91qif2cdbng1itkjomd0g646#msg104689', u'Re:Saber ID De Un objeto JQuery ?'), (u'https://underc0de.org/foro/dudas-generales-121/la-ram/msg104688/?topicseen;PHPSESSID=ub91qif2cdbng1itkjomd0g646#msg104688', u'Re:Ocupar la memoria RAM de procesos inutiles'), (u'https://underc0de.org/foro/dudas-generales-121/kali-payload-y-no-ip-ataque-fuera-lan/msg104687/?topicseen;PHPSESSID=ub91qif2cdbng1itkjomd0g646#msg104687', u'Re:kali payload y no-ip ataque fuera lan'), (u'https://underc0de.org/foro/dudas-generales-121/android-duda-base-de-datos/msg104686/?topicseen;PHPSESSID=ub91qif2cdbng1itkjomd0g646#msg104686', u'Re:Android -  Duda Base de Datos para camareros en un bar'), (u'https://underc0de.org/foro/dudas-generales-121/dudas-sin-aclarar/msg104685/?topicseen;PHPSESSID=ub91qif2cdbng1itkjomd0g646#msg104685', u'Re:Empezar en las ramas de Phishing y Programaci\xf3n'), (u'https://underc0de.org/foro/dudas-generales-121/stub-limpio-server-detectado-por-que/msg104684/?topicseen;PHPSESSID=ub91qif2cdbng1itkjomd0g646#msg104684', u'Re:stub limpio server detectado, por que?')]


Les dejo como ejercicio hacer una funcion que devuelva una lista con todos los nombres de los usuarios que aparecen abajo de " Usuarios activos en los últimos 25 minutos:", llamarla y mostrar el resultado. Cuando lo tengan o se traben posteen el codigo

Puede ser que tengan que escapar algunos caracteres especiales, aunque lo dudo. Si hace falta, acuerdense de que es escapan con \
También puede ser que hagan una expresion regular que matchee con mas datos que los que buscamos. Por ejemplo, puede ser que traiga los nombres de los usuarios que salen al lado de los titulos de los posts. Pueden tratar de hacer una expresion regular mas compleja, o capaz dos: una que matchee el div en el que estan los datos y otra que saque los usuarios de ahi adentro.


Que raro que ya vi dos consultas en el irc sobre esto, pero nadie se pone a practicar

Que tal, interesante lo que has compartido.
En el metodo search() estamos buscando un match, por lo que debemos saber de que esta rodeado y atrapar ese texto, al menos asi lo entendi.

Lo que no entendi es como el metodo findall() sabe que quiero ver los post y no la lista de usuarios?

En search() le aclaramos que queremos ver pero en findall() no se llega a explicar como sabe lo que quiero ver exactamente.

Perdon si es una pregunta muy basica.

Se lo pasas en el primer parametro.

Estos dos codigos hacen lo mismo:
Código: php

regexp = '<dt><strong><a href="(.*?)" rel="nofollow">(.*?)</a></strong>'
resultado = re.findall(regexp, web.text)

Código: php

resultado = re.findall('<dt><strong><a href="(.*?)" rel="nofollow">(.*?)</a></strong>', web.text)


fijate que la expresion regular para capturar los usuarios es distinta a la que captura los links

Bueno para seguir un poco con el taller aquí les pongo mi code con la pequeña tarea que seth nos dejó.
Me tome la molestia de desarrollarlo un poco ya que hace años que no programo y estoy retomando todo nuevamente y bueno como ven, he vuelto a la comunidad.

Aqui les dejo el code:
Código: python
# -*- coding: UTF-8 -*
import requests, re

url = "https://www.underc0de.org/foro/index.php"
web = requests.get(url)

def staff_user():
staffuser = '<a href=".*?" style="color: #FF8000;">(.*?)</a>,'
resultado = re.findall(staffuser, web.text)
print '[+] Staff LIST: ' + '\n'
for users in resultado:
print users.encode('utf-8') + ''

def normal_user():
normaluser = '<a href=".*?">(.*?)</a>,'
resultado = re.findall(normaluser, web.text)
print '\n' + '[+] Users LIST: ' + '\n'
for users in resultado:
print users.encode('utf-8') + ''

def online_users():
online = 'Visitantes, (.*?) Usuarios'
resultado = re.search(online, web.text)
print '** Online users' +' ['+str(resultado.group(1))+']'+' **' + '\n'

if __name__ == '__main__':
online_users()
print 'ONLINE USERS: ' + '\n'
staff_user()
normal_user()
else:
exit(0)


Basicamente lo que hace es mostrar la cantidad de usuarios conectados, igual como mostró seth más arriba e imprime una lista de usuarios conectados, tanto 'staff' como usuarios normales.

Tengo un pequeño problema en ese code que cuando lo ejecuto también me imprime foros y subforos de la pagina, como por ejm: 'Pentesting', 'shell', hasta me imprime la licencia del foro y me lo imprime como 'SMF &copy; 2015' a ver si ustedes pueden editarlo y decirme que hice mal, saludos y sigan con el taller!

PABLO ESCOBAR.

Bien, el problema es que esta regex matchea mas cosas de las que deberia:
<a href=".*?">(.*?)</a>

Fijate que todos los links a los perfiles de los usuarios empiezan con 'No tienes permitido ver los links. Registrarse o Entrar a mi cuenta', podes incluir eso en lugar de reemplazarlo por .*?
O sea, el .*? lo vas a tener que dejar porque no sabes como sigue el link, pero podes matchear solo los que van a perfiles

Eso tambien te va a matchear links como este:
Código: php
						<p><span><a href="https://underc0de.org/foro/profile/cybervaca/">cybervaca</a>	en <a href="https://underc0de.org/foro/ingenieria-inversa/(-net)-crackme-by-chemitazzhd-c/msg0/?boardseen#new" title="Re:[.NET] CrackMe By ChemitaZzHD - C#">Re:[.NET] CrackMe By Che...</a></span><br />


Una solucion: todos los usuarios que nos interesan son los que estan adentro de <p class="inline smalltext">. Podes matchear primero lo que esta adentro de ese elemento y despues con ese resultado correr las demas regexp

Hoy pude conectarme e hice la tarea del taller jajaja
me costo mucho ya que no manejo python pero aqui esta

Código: php

import requests
import re
web = requests.get("https://underc0de.org/foro/index.php")
regexp = '<a href="https://underc0de.org/foro/profile/.*?">(.*?)</a>'
resultado = re.findall(regexp, web.text)
print resultado


gracias por la enseñanza muy interesante lo aprendido, espero que sigan las clases en este taller, Saludos.

PD: el codigo muestra en pantalla lo siguiente:
Código: php
[u'Gabriela', u'USER1696960', u'Gabriela', u'matitk', u'Stiuvert', u'Nobody', u'selohu', u'S@nde', u'str0nasfck', u'seth', u'unkdown', u'hati', u'circunsxik', u'cybervaca', u'else\xf1orx', u'EPSILON', u'JoanSerna', u'blackdrake', u'Stiuvert', u'Cl0udswX', u'Cl0udswX', u'Dr__Nesto', u'BadB0y_4', u'graphixx', u'cnfs', u'Expermicid', u'ExtaZys', u'Expermicid', u'79137913', u'Expermicid', u'Doddy', u'grep', u'Zentraedi', u'79137913', u'79137913', u'rollth', u'edgarito_2012', u'graphixx', u'ExtaZys', u'Expermicid', u'JJx', u'Subzer', u'graphixx', u'rush', u'ThePlus', u'79137913', u'Flame', u'DeBobiPro', u'Vasyyyl', u'DeBobiPro', u'Hu3c0', u'DeBobiPro', u'graphixx', u'graphixx', u'DeBobiPro', u'austro180', u'ANTRAX', u'Slenderhack', u'rreedd', u'PikachuDorado', u'DiegoTk', u'PikachuDorado', u'Uservzk80', u'Cygog', u'Digital Shadow', u'Cl0udswX', u'Satyricon', u'TioNacho', u'selohu', u'selohu', u'Subzer', u'else\xf1orx', u'Stiuvert', u'Stiuvert', u'Stiuvert', u'julianamorenot', u'79137913', u'po6xsecpo', u'voltage', u'fbian220', u'selohu', u'bridth', u'Subzer', u'Flamer', u'BlackBlex', u'ECVS', u'tondrax', u'matitk', u'rush', u'kronos.boca', u'Jimeno', u'Once', u'julianamorenot', u'Zentraedi', u'neodementor', u'ghro77', u'AJOP', u'ANTRAX', u'mingoandroid', u'cordobez10', u'pema94', u'Falsifikeitor', u'morodog', u'Maxfaider', u'Cr1m1n4l', u'jorge705', u's4ull', u'black magdala', u'TaylorSwift', u'nexusz', u'else\xf1orx', u'Stiuvert', u'noxonsoftwares', u'drotha2', u'ajcomputerses', u'VinC90', u'Kevin Howard', u'diosjeremy', u'adragon', u'3x0rt', u'Kzuma', u'puntoCL', u'roadd', u'zaphiel', u'zydar', u'dehombreadios', u'antoniocr', u'rosav', u'Bebeto', u'graphixx', u'alfred', u'Empty glass', u'Stuxnet', u'jambres', u'Ley20Mil', u'Tatoluckyfox', u'jasan1996', u'Carvachorum', u'jero433', u'DiegoTk', u'UnK', u'neuk', u'Gabriela', u'rollth', u'R.JimSor', u'blackdrake', u'iatsm', u'guilreto', u'Rony1545', u'ChitoEBM', u'manoverde', u'Vasyyyl', u'Hxgm', u'USER1696960', u'Unname', u'Jesuss', u'viagr4', u'roserrva', u'jose angel', u'Darksen', u'FUMATRONIC', u'Bishop', u'Lapazouhakcs', u'zahay', u'q3rv0', u'djbeat', u'cborgon', u'salem', u'koopa2', u'isaac_calvet', u'blueksyx', u'tesla', u'Kode', u'hum4n3xpl01t', u'dannekmr', u'mortico10', u'tito_chua', u'Forken', u'iamcholo', u'xavicibi', u'Joni2012', u'Chriseric', u'rab.', u'Yoskor', u'Cl0udswX', u'stegic', u'Keycarty', u'Nachoct', u'boguies', u'Slenderhack', u'jsDotx3', u'HomeGuard', u'Satyricon', u'aforistis', u'bruno45', u'coloradoxx', u'hati', u'pentestbox', u'harry_arg', u'M1ndCr4ck', u'ubbosatlahlk', u'gerard14', u'Bartrack', u'B4TB0YFUCK3R', u'DIANA YIRET', u'jonycancer', u'pirula01', u'BadB0y_4', u'kreator2178', u'Pytness', u'luff1', u'DarkMulero', u'guerraypaz46', u'Goyo', u'EvilSoft', u'glorytime', u'AnonimoArc', u'Zeroax', u'nansoft', u'yankele', u'marcxiri11', u'terminator2016', u'GOHANCKZ', u'linuxblt', u'zenzey909', u'Cronos', u'moonify', u'Valst', u'TR31N0RD', u'slashh865', u'judas6409', u'Adrian72112', u'beto_201', u'TheBeyonder', u'peleon02', u'djbob', u'Pricker', u'Cr4id3r', u'Alchemist', u'NyxKazuya', u'KR1ST4N', u'troki2011', u'inaki19899', u'lucas.dega', u'Byakko', u'ricci2diaz', u'santinho', u'zadeno3', u'ermaquina97', u'wblack', u'jfr4n', u'undercodeuser', u'srzeta', u'DarkXploitz', u'EnricCat', u'Blank', u'13tm3nt3r', u'ro0tmag', u'xxxcoenxxx', u'jsuarez1965', u'internauta', u'blanix', u'lamepie', u'wactor', u'rus1365', u'circunsxik']


hay una forma de quitar esa  u'(nombre de usuaruio), no pude quitar la u', pero al menos salio el objetivo, gracias.

La u está bien, indica que es un string unicode
Si metes un for que recorra la lista y muestre los strings uno por uno, no va a salir

Fijate que te apsa lo mismo que a subzer, te está trayendo datos de mas
En tu caso, trae gabriela varias veces, debe ser porque hizo posts y salen aca: No tienes permitido ver los links. Registrarse o Entrar a mi cuenta



No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Fijate que te apsa lo mismo que a subzer, te está trayendo datos de mas
En tu caso, trae gabriela varias veces, debe ser porque hizo posts y salen aca: No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

Si recien me doy cuenta de eso, se repiten varios usuarios, vere como resolverlo.

Esta es una solución alternativa a usar expresiones regulares. Para el caso de web scrapping, a mi parecer el uso de las expresiones regulares no es de lo más adecuado ni tampoco sano como para permitirnos conservar la integridad mental  ;D

En este ejemplo uso etree y xpath

Código: python
import urllib2
from lxml import etree

def get_users(html):
    parsedHTML = etree.HTML(html)
    pelement = parsedHTML.xpath('//div[@id="upshrinkHeaderIC"]/p[@class="inline smalltext"]')[0]
    return([href.split("/")[-2] for href in pelement.xpath("a/@href") if "profile" in href])


if __name__ == "__main__":
    response =  urllib2.urlopen("https://underc0de.org/foro/index.php")
    print(get_users(response.read()))


Código: bash
['1410', 'TheAssassinExp', 'arthusu', 'Jonydakid', 'str0nasfck', 'boguies', 'skrillex', 'zenzey909', 'AFelipeTrujillo', 'skwlk', 'wilkin07', 'iamcholo', 'grep', 'Elixus', 'coke951', 'Victimous', 'cnfs', 'Zentraedi', 'Gabriela', 'nkmil', 'Amorrua', 'slipknotoy', 'mariodos', 'rejeanan', 'andrei_phantom', 'BlackBlex', 'xrahitel', 'DaLeXx007', 'DammZ', 'Stuxnet', 'T3mpor4lGN', 'javichoooz', 'YENA', 'ceroMee', 'blackdrake', 'luff1', 'dtubio', 'TioNacho', 'drakoniano', 'gerard14', 'blacksucces', 'servventas', 'Pablo2011', 'blanco', 'erguli', 'noxon', 'graphixx', 'Bernatixer', 'creeper22', 'Rapzus', 'quino32', 'Stiuvert', 'phr4ckl0t', 'R.JimSor', 'roberton84', 'ice.modding', 'Flame', 'theplageblack', 'Joni2012', 'antoniocr', 'japheth1518', 'LionSec', 'Gho0st', 'hack066', 'roadd', 'selohu', 'catami61', 'PikachuDorado', 'Eduardez', 'Se%C3%B1orQ', 'hum4n3xpl01t', 'EPSILON', 'drok3r', 'tito_chua', 'Chriseric', 'cborgon', 'pab%20mac', 'VinC90', 'L3gacy', 'RICY', 'ninfaaruna', 'troki2011', 'Yoskor', 'rollth', 'Flemon', 'pablormago', 'Hu3c0', 'alfred', 'Pistojo', 'darkside85', 'hati', 'nitro_x_net', 'rodanet', 'adragon', 'Meteorrr', 'julen', 'Hactot', 'Rafaelpb14', 'Nkizux', 'Blank', 'Carvachorum', 'lestherelyhuneth123', 'AndresMaicho', 'wicope', 'AndrewMa', 'BadB0y_4', 'caradepoio', 'RickSanchez', 'zaphiel', 'redferne', 'Nik', 'wblack', 'mbwun28']



Saludos

Yo lo resolví de esta forma: decidí separar el bloque donde están los usuarios conectados para hacer la búsqueda de expresiones regulares solamente en esa parte, de forma que evitamos obtener resultados repetidos ya que hay enlaces a los perfiles de los usuarios en casi todo el index, también, muchas gracias seth y a todos los que aportaron con su respuesta, este taller me ha ayudado bastante.

Código: python
import requests
import re

resultado = requests.get('https://underc0de.org/foro/index.php')

resultado = resultado.text

# Obtengo el indice de la cadena Usuarios en linea para realizar la busqueda desde ese punto en adelante
# Y asi evitar obtener resultados repetidos
encuentra1 = resultado.find('Usuarios en Línea')

bloque = resultado[encuentra1:]

regex = '<a href="https://underc0de.org/foro/profile/.*?>(.*?)</a>'

lista_usuarios = re.findall(regex,bloque)

print(lista_usuarios)


El resultado es este:
Código: php
['79137913', 'SirVitin', 'Gabriela', 'noah_elbec', 'th3binary', 'dhenux', 'nicolasheise', 'darkalinow', 'Flame', 'Nik', 'madrileña',
'Bael', 'S1ST3MG4M3R7', 'ghostshadow666', 'grep', 'Jackaiser', 'Decode', 'puntoCL', 'noxonsoftwares', 'Stuxnet', 'Yustuz', '¡Gabriel!
', 'animanegra', 'kuarsa', 'scalvhh', 'Stiuvert', 'Christian Fer', 'ampali', 'Yuki', 'WilliamONeill', 'HckH3x', 'Amorrua', 'noyka', '
xyz', 'corpsebalu', 'marcchile', 'user_en1gm4', 'David Bassara', 'phr4ckl0t', 'zenzey909', 'Andrey', 'viobano', 'Cr4id3r', 'n0z', 'Gn
0m3', 'edgoes', 'M03's']