Web scraping o raspado web, es una técnica utilizada mediante programas de software para extraer información de sitios web. Usualmente, estos programas simulan la navegación de un humano en la World Wide Web ya sea utilizando el protocolo HTTP manualmente, o incrustando un navegador en una aplicación.
En este ejemplo se hará web scraping utilizando Python, utilizando la librería «scrapingML«. En el siguiente enlace se puede encontrar información sobre cómo instalar una librería Python desde GitHub si se está utilizando el gestor de paquetes Miniconda: «Gestión de paquetes Python con Miniconda«
Funcionamiento de la librería
Código de la interfaz de usuario «app.py»
import os
import json
import time
import requests
import ast
#Abriendo config.json
filename = open('config.json')
config = filename.read()
config = ast.literal_eval(config)
f_user = config['f_user']
i_user = config['i_user']
l_user = config['l_user']
f_pass = config['f_pass']
i_pass = config['i_pass']
l_pass = config['l_pass']
new_config = {'f_user':f_user,'f_pass':f_pass,'i_user':i_user,'i_pass':i_pass,'l_user':l_user,'l_pass':l_pass,'f_autenticar':'si','i_autenticar':'si','l_autenticar':'si','autenticar':'si'}
def buscar_id():
os.system('cls')
id = input("Ingrese el ID: ")
datos = {}
url = 'https://www.instagram.com/'+id
inst = requests.get(url)
url = 'https://www.facebook.com/'+id
face = requests.get(url)
url = 'https://www.linkedin.com/in/'+id
li = requests.get(url)
if inst.status_code == 200:
datos['instagram'] = "existe"
else:
datos['instagram'] = "no existe"
if face.status_code == 200:
datos['facebook'] = "existe"
else:
datos['facebook'] = "no existe"
if li.status_code == 200:
datos['linkedin'] = "existe"
else:
datos['linkedin'] = "no existe"
return datos
os.system('cls')
print("Opciones para la ejecución de Scrapping")
opcion_incorrecta = 1
while opcion_incorrecta == 1:
print("1 Social scrapping")
print("2 Social scrapping sin autenticar\n")
opcion = input("Digite el número de opción seguido de la tecla Enter: ")
if opcion =='1':
new_config['f_autenticar']='si'
new_config['i_autenticar']='si'
new_config['l_autenticar']='si'
opcion_incorrecta = 0
opcion_incorrecta2 = 1
os.system('cls')
print("Ingreso de credencialess")
op_masCredenciales="0"
while opcion_incorrecta2 == 1 or op_masCredenciales=="1":
print("1 Facebook")
print("2 Instagram")
print("3 inkedin\n")
op_credenciales = input("Digite el número de opción seguido de la tecla Enter: ")
if op_credenciales == '1':
opcion_incorrecta2 = 0
os.system('cls')
print("Ingrese credenciales de Facebook")
f_user = input("Usuario: ")
f_pass = input("Contraseña: ")
new_config['f_user']=f_user
new_config['f_pass']=f_pass
elif op_credenciales == '2':
opcion_incorrecta2 = 0
os.system('cls')
print("Ingrese credenciales de Instagram")
i_user = input("Usuario: ")
i_pass = input("Contraseña: ")
new_config['i_user']=i_user
new_config['i_pass']=i_pass
elif op_credenciales == '3':
opcion_incorrecta2 = 0
os.system('cls')
print("Ingrese credenciales de Linkedin")
l_user = input("Usuario: ")
l_pass = input("Contraseña: ")
new_config['l_user']=l_user
new_config['l_pass']=l_pass
else:
os.system('cls')
print("Ingrese una opción válida")
if opcion_incorrecta2 == 0:
os.system('cls')
print("Desea ingresar más credenicales")
opcion_incorrecta3 = 1
while opcion_incorrecta3 == 1:
print("1 Si")
print("2 No")
op_masCredenciales = input("Digite el número de opción seguido de la tecla Enter: ")
if op_masCredenciales == "1":
opcion_incorrecta3 = 0
os.system('cls')
print("Ingreso de credencialess")
elif op_masCredenciales =="2":
opcion_incorrecta3 = 0
#Para facebook
if config['f_user'] == f_user and config['f_pass'] == f_pass:
new_config['f_autenticar']='no'
#Archivo de configuración
flename = 'config.json'
with open(flename, 'w') as f:
f.write(str(new_config))
#Para instagram
if config['i_user'] == i_user and config['i_pass'] == i_pass:
new_config['i_autenticar']='no'
#Archivo de configuración
flename = 'config.json'
with open(flename, 'w') as f:
f.write(str(new_config))
#Para instagram
if config['l_user'] == l_user and config['l_pass'] == l_pass:
new_config['l_autenticar']='no'
#Archivo de configuración
flename = 'config.json'
with open(flename, 'w') as f:
f.write(str(new_config))
#Archivo de configuración
flename = 'config.json'
with open(flename, 'w') as f:
f.write(str(new_config))
else:
os.system('cls')
print("Ingrese una opción válida")
if op_masCredenciales == '2':
os.system('cls')
print("Herramientas disponibles")
opcion_incorrecta4 = 1
while opcion_incorrecta4 == 1:
print("1 Ejecutar Facebook Scrapping")
print("2 Ejecutar Instagram Scrapping")
print("3 Ejecutar Linkedin Scrapping")
print("4 Buscar ID en redes sociales")
print("5 Salir\n")
op_tools = input("Digite el número de opción seguido de la tecla Enter: ")
if op_tools == '1':
os.system('cls')
opcion_incorrecta4 = 0
print("Ejecutando Facebook Scrapping...")
print(config['f_user'])
print(f_user)
exec(compile(open("fb2.py","rb").read(),"fb2.py","exec"))
elif op_tools == '2':
os.system('cls')
opcion_incorrecta4 = 0
print("Ejecutando Instagram Scrapping...")
exec(compile(open("inst2.py","rb").read(),"inst2.py","exec"))
# time.sleep(5)
elif op_tools == '3':
os.system('cls')
opcion_incorrecta4 = 0
print("Ejecutando Linkedin Scrapping")
exec(compile(open("linkedin.py","rb").read(),"linkedin.py","exec"))
elif op_tools == '4':
os.system('cls')
opcion_incorrecta4 = 0
print("Buscando ID en redes sociales")
datos = buscar_id()
print(datos)
elif op_tools == '5':
os.system('cls')
print("Termiando sesión")
opcion_incorrecta4 = 0
else:
os.system('cls')
print("Ingrese una opción válida")
elif opcion == '2':
new_config['autenticar']='no'
#Archivo de configuración
flename = 'config.json'
with open(flename, 'w') as f:
f.write(str(new_config))
opcion_incorrecta = 0
os.system('cls')
print("Herramientas disponibles")
opcion_incorrecta5 = 1
while opcion_incorrecta5 == 1:
print("1 Ejecutar Facebook Scrapping")
print("2 Ejecutar Instagram Scrapping")
print("3 Ejecutar Linkedin Scrapping")
print("4 Buscar ID en redes sociales")
print("5 Salir\n")
op_tools = input("Digite el número de opción seguido de la tecla Enter: ")
if op_tools == '1':
os.system('cls')
opcion_incorrecta5 = 0
print("Ejecutando Facebook Scrapping")
exec(compile(open("fb2.py","rb").read(),"fb2.py","exec"))
time.sleep(5)
elif op_tools == '2':
os.system('cls')
opcion_incorrecta5 = 0
print("Ejecutando Instagram Scrapping")
exec(compile(open("inst2.py","rb").read(),"inst2.py","exec"))
time.sleep(5)
elif op_tools == '3':
os.system('cls')
opcion_incorrecta5 = 0
print("Ejecutando Linkedin Scrapping")
exec(compile(open("linkedin.py","rb").read(),"linkedin.py","exec"))
time.sleep(5)
elif op_tools == '4':
os.system('cls')
opcion_incorrecta5 = 0
print("Buscando ID en redes sociales")
datos = buscar_id()
print(datos)
elif op_tools == '5':
os.system('cls')
opcion_incorrecta5 = 0
else:
os.system('cls')
print("Ingrese una opción válida")
new_config['autenticar']='si'
flename = 'config.json'
with open(flename, 'w') as f:
f.write(str(new_config))
else:
os.system('cls')
print("Ingrese una opción válida")
print("Scrap4 terminado")
# #Vaciar config
# flename = 'config.json'
# with open(flename, 'w') as f:
# f.write("")
Código de «fb2.py»
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import requests, pickle
import time
import sys
import argparse
import json
import ast
from openpyxl import Workbook
import html as html_library
from scrapingML.scrapingML import *
#-------------------------------------------------------------------------
#-----------------------Configuraciones de login--------------------------
filename = open('config.json')
config = filename.read()
config = ast.literal_eval(config)
user = config['f_user']
password = config['f_pass']
# print(config['f_user'])
# print(config['f_pass'])
#----------------------------------------------------------------------------
#-------------------------------LOGIN----------------------------------------
if config['f_autenticar']=='si' and config['autenticar']=='si':
session = fb_login(user,password)
fb_save_session(session)
elif config['f_autenticar']=='no':
session = fb_retrieve_session()
#----------------------------------------------------------------------------
#-------------------SCRAPPING DE INFORMACIÓN DE USUARIOS---------------------
#Lectura de los perfiles objetivo del archivo txt
print('SCRAPPING INFORMACIÓN DE USUARIO')
archivo = open('instagram_target_aux.txt',"r")
arch = archivo.read()
if len(arch)==0:
target = open("facebook_target.txt", "r")
urls = []
for line in target:
urls.append(line.strip())
elif len(arch)>0:
archivo = open("instagram_target_aux.txt", "r")
urls = []
for line in archivo:
urls.append(line.strip())
archivo = open("instagram_target_aux.txt", "w")
archivo.write("")
#Para todos los usuarios
for url_user in urls:
print('Scrapping usuario: %s'%url_user)
cookies = ""
for name,value in session.cookies.items():
cookies = cookies + name +'=' +value+';'
# print(name,':',value)
session.headers.update({'Host': 'www.facebook.com',
'path': url_user+'/about',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:68.0) Gecko/20100101 Firefox/68.0',
'Accept': '',
'Content-Type': '',
'Accept-Language': '',
'Accept-Encoding': '',
'Connection': 'keep-alive',
'Cookie': cookies,
'Upgrade-Insecure-Requests': '1',
'TE': 'Trailers',
'Pragma':'no-cache',
'Cache-control':'no-cache'
})
time.sleep(5)
r3 = session.get(url_user+'/about')
print(r3.status_code, r3.url)
for resp in r3.history:
print (resp.status_code, resp.url)
html = html_library.unescape(r3.text)
info = {}
#Para el nombre:
try:
nombre_usuario = html.split('pageTitle">')[1].split('<')[0]
nombre_usuario = nombre_usuario.replace('|','')
info['nombre'] = nombre_usuario
except:
info['nombre'] = ''
# #Para el trabajo:
# try:
# nombre = html.split('Trabaja en <a')[1].split('>')[1].split('<')[0]
# info['trabajo'] = nombre
# except:
# info['trabajo'] = ''
# #Para la educación
# try:
# nombre = html.split('Ha estudiado')[1].split('en ')[0]
# info['educacion'] = nombre
# except:
# info['educacion'] = ''
#Para la ciudad actual:
try:
nombre = html.split('Vive en <')[1].split('>')[1].split('<')[0]
info['ciudad_actual'] = nombre
except:
info['ciudad_actual'] = ''
#Ciudad natal:
try:
nombre = html.split('Vive en <')[1].split('>De')[1].split('>')[2].split('<')[0]
info['ciudad_natal'] = nombre
except:
info['ciudad_natal'] = ''
#Para los trabajos y formación académica:
cookies = ""
for name,value in session.cookies.items():
cookies = cookies + name +'=' +value+';'
session.headers.update({'Host': 'www.facebook.com',
'path': url_user+'/about',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:68.0) Gecko/20100101 Firefox/68.0',
'Accept': '',
'Content-Type': '',
'Accept-Language': '',
'Accept-Encoding': '',
'Connection': 'keep-alive',
'Cookie': cookies,
'Upgrade-Insecure-Requests': '1',
'TE': 'Trailers',
'Pragma':'no-cache',
'Cache-control':'no-cache'
})
time.sleep(5)
r4 = session.get(url_user+'/about?section=education')
print(r4.status_code, r4.url)
try:
nombre = r4.text.split('Empleo</span>')[1].split('académica</span')[0].split('data-hovercard-prefer-more-content-show="1">')
# nombre = nombre.split('ref=profile" title="')
cont = 0
empleos = []
cargo = ""
for a in nombre:
if cont != 0:
try:
cargo = a.split('_173e _50f8 _2ieq"><div class="fsm fwn fcg">')[1].split('<')[0]
except:
cargo = ''
empleos.append(cargo +' '+ a.split('</a>')[0])
cont = cont +1
except:
print("No se econtraron empleos")
# Para la educación
try:
nombre = r4.text.split('académica</span')[1].split('Fotos<span')[0].split('data-hovercard-prefer-more-content-show="1">')
# nombre = nombre.split('ref=profile" title="')
cont = 0
educacion = []
cargo = ""
for a in nombre:
if cont != 0:
try:
cargo = a.split('_173e _50f8 _2ieq"><div class="fsm fwn fcg">')[1].split('<')[0]
except:
cargo = ''
educacion.append(cargo +' '+ a.split('</a>')[0])
cont = cont +1
except:
print("No se econtró Formación Académica")
#Para las relaciones:
cookies = ""
for name,value in session.cookies.items():
cookies = cookies + name +'=' +value+';'
session.headers.update({'Host': 'www.facebook.com',
'path': url_user+'/about',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:68.0) Gecko/20100101 Firefox/68.0',
'Accept': '',
'Content-Type': '',
'Accept-Language': '',
'Accept-Encoding': '',
'Connection': 'keep-alive',
'Cookie': cookies,
'Upgrade-Insecure-Requests': '1',
'TE': 'Trailers',
'Pragma':'no-cache',
'Cache-control':'no-cache'
})
time.sleep(5)
r4 = session.get(url_user+'/about?section=relationship')
print(r4.status_code, r4.url)
flename = 'Facebook_relaciones.html'
with open(flename, 'wb') as f:
f.write(r4.content)
try:
nombre = r4.text.split('Familiares</span>')[1].split('data-hovercard-prefer-more-content-show="1">')
# nombre = nombre.split('ref=profile" title="')
cont = 0
relaciones = []
cargo = ""
for a in nombre:
if cont == 0:
try:
link = a.split('href="https://')[1].split('"')[0]
except:
link = ''
if cont != 0:
try:
cargo = a.split('<div class="fsm fwn fcg">')[1].split('<')[0]
except:
cargo = ''
relaciones.append(cargo +' '+ a.split('</a>')[0] + ' ' + link)
try:
link = a.split('href="https://')[1].split('"')[0]
except:
link = ''
cont = cont +1
except:
print("No se econtraron relaciones")
try:
nombre = r4.text.split('Situación sentimental</span>')[1].split('</code>')[0].split('data-hovercard-prefer-more-content-show="1">')
# nombre = nombre.split('ref=profile" title="')
sentimental = []
cargo = ""
link = ''
try:
cargo = nombre[1].split('_173e _50f8 _2ieq">')[1].split('<')[0]
except:
cargo = ''
try:
link = nombre[0].split('href="')[1].split('"')[0]
except:
link = ''
sentimental.append(cargo +' '+ a.split('</a>')[0] + ' ' + link)
except:
print("No se econtró situación sentimental")
print(info)
#----------------------------------------------------------------------------
#--------------------------BÚSQUEDA DE OTRAS REDES---------------------------
print("BÚSQUEDA DE OTRAS REDES")
# Para los libros
cookies = ""
for name,value in session.cookies.items():
cookies = cookies + name +'=' +value+';'
session.headers.update({'Host': 'www.facebook.com',
'path': url_user+'/about',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:68.0) Gecko/20100101 Firefox/68.0',
'Accept': '',
'Content-Type': '',
'Accept-Language': '',
'Accept-Encoding': '',
'Connection': 'keep-alive',
'Cookie': cookies,
'Upgrade-Insecure-Requests': '1',
'TE': 'Trailers',
'Pragma':'no-cache',
'Cache-control':'no-cache'
})
parametros = {'section':'contact-info'}
time.sleep(5)
rr = session.get(url_user+'/about',params=parametros)
print(rr.status_code, rr.url)
for resp in rr.history:
print (resp.status_code, resp.url)
if rr.text.find('https%3A%2F%2Finstagram.com%2F') != -1 and rr.status_code == 200:
print("Se ha encontrado un perfil de instagram")
try:
url_instagram = rr.text.split('https%3A%2F%2Finstagram.com%2F')[1].split('%')[0]
url_instagram = 'https://www.instagram.com/'+url_instagram
print("Almacenando perfil encontrado en facebook_target_aux.txt ...")
flename = 'facebook_target_aux.txt'
with open(flename, 'a+') as f:
f.write(url_instagram+'\n')
except:
pass
else:
print("No se encontraron otras redes")
#----------------------------------------------------------------------------
#--------------------------SCRAPPING DE LAS FOTOS----------------------------
print('SCRAPPING: FOTOS ')
session.headers.update({'Host': 'mbasic.facebook.com',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:68.0) Gecko/20100101 Firefox/68.0',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Content-Type': '',
'Accept-Language': '',
'Accept-Encoding': '',
'Connection': 'keep-alive',
'Cookie': cookies,
'Upgrade-Insecure-Requests': '1',
'TE': 'Trailers',
'Pragma':'no-cache',
'Cache-control':'no-cache'
})
time.sleep(5)
r6 = session.get(url_user+'/photos')
#Llamada a cada página de fotos (cada pagina contiene 12 fotos)
#Primera página de fotos:
lista_fotos_total = []
try:
url_fotos = 'https://mbasic.facebook.com'+url_user.split(".com")[1] + '/photoset/pb.'
url_fotos = url_fotos + r6.text.split('set=pb.')[1].split('&')[0]
url_fotos = url_fotos + '/'
parametros = {
'owner_id':r6.text.split('owner_id=')[1].split('"')[0],
'back_uri':r6.text.split('back_uri=')[1].split('"')[0]
}
time.sleep(5)
r7 = session.get(url_fotos, params = parametros)
def lista_fotos(html): #Generar lista de fotos encontradas
lista_fotos = []
lista = html.split('fbid=')
cont = 0
for elemento in lista:
if cont !=0:
lista_fotos.append(elemento.split('&')[0])
cont = cont +1
return lista_fotos
lista_fotos_total = lista_fotos(r7.text)
#Siguientes páginas de fotos
conta = 0
while r7.text.find('fbid=') != -1:
conta = conta +1
print(conta)
time.sleep(3)
try:
url_fotos = 'https://mbasic.facebook.com' + url_user.split(".com")[1] + '/photoset/pb.'
url_fotos= url_fotos + r7.text.split('pb.')[1].split('/')[0]
url_fotos = url_fotos + '/'
except:
break
parametros = {
'owner_id':r7.text.split('owner_id=')[1].split('&')[0],
'offset':r7.text.split('offset=')[1].split('&')[0],
'back_uri':r7.text.split('back_uri=')[1].split('"')[0]
}
time.sleep(5)
r7 = session.get(url_fotos, params = parametros)
lista_fotos_total = lista_fotos_total + lista_fotos(r7.text)
except:
print('No se puede acceder a las fotos')
#Datos de cada foto de la lista_fotos_total
session.headers.update({'Host': 'www.facebook.com'})
def datos_fotos(url):
r8 = session.get(url)
print(r8.status_code, r8.url)
html = r8.text
try:
descripcion = html.split('pageTitle">')[1].split('</title>')[0]
if descripcion.find('|')!=-1:
descripcion = descripcion[0:descripcion.find('|')-1]
elif descripcion.find('-')!=-1:
descripcion = descripcion[descripcion.find('-')+2:len(descripcion)]
except:
descripcion = ""
#Localzación de la foto:
try:
if html.find('está aqui') != -1:
localizacion = html[r8.text.find('está aquí')+11::].split('<')[0]
elif html.find('en <') != -1:
localizacion = html.split('en <')[1].split('">')[1].split('<')[0]
else:
localizacion = ""
except:
localizacion = ""
return descripcion,localizacion
fotos = {}
cont = 0
for elemento in lista_fotos_total:
cont = cont +1
print("Foto %d"%cont)
url = 'https://www.facebook.com/photo.php?fbid='+elemento
time.sleep(5)
descripcion, localizacion = datos_fotos(url)
fotos['foto%d'%cont]= {'url':url}
fotos['foto%d'%cont]['descripcion'] = descripcion
fotos['foto%d'%cont]['localizacion'] = localizacion
print(fotos['foto%d'%cont])
#----------------------------------------------------------------------------
#--------------------------EXPORTACIÓN A EXCEL-------------------------------
print('GENERANDO ARCHIVO')
wb = Workbook()
ws1 = wb.active
ws1.title='Datos'
cont = 5
ws1['A1'] = 'URL'
ws1['A2'] = 'nombre'
ws1['A3'] = 'ciudad_actual'
ws1['A4'] = 'ciudad_natal'
ws1['B1'] = url_user
ws1['B2'] = info['nombre']
ws1['B3'] = info['ciudad_actual']
ws1['B4'] = info['ciudad_natal']
for i in empleos:
ws1['A'+str(cont)] = 'trabajo'
ws1['B'+str(cont)] = i
cont = cont +1
for i in educacion:
ws1['A'+str(cont)] = 'estudios'
ws1['B'+str(cont)] = i
cont = cont +1
for i in relaciones:
ws1['A'+str(cont)] = 'familia y relaciones'
ws1['B'+str(cont)] = i
cont = cont +1
ws1['A'+str(cont)] = 'familia y relciones'
ws1['B'+str(cont)] = sentimental[0]
ws2 = wb.create_sheet('Fotos')
ws2['A1'] = 'URL'
ws2['B1'] = 'DESCRIPCION'
ws2['C1'] = 'LOCALIZACION'
for num in range(1, len(fotos)+1):
fila = num +1
ws2['A%d'%fila] = fotos['foto%d'%num]['url']
ws2['B%d'%fila] = fotos['foto%d'%num]['descripcion']
ws2['C%d'%fila] = fotos['foto%d'%num]['localizacion']
wb.save('facebook_%s.xlsx'%nombre_usuario)
# ------------------------------------------------------------------------
# --------------------------Scrapping de redes encontradas----------------
#Lectura de los perfiles objetivo del archivo txt
archivo = open('facebook_target_aux.txt',"r")
arch = archivo.read()
if len(arch)==0:
pass
elif len(arch)>0 and rr.status_code == 200:
opcion_incorrecta =1
print("Se han encontrado perfiles de instagram, ¿desea ejecutar Instagram Scrapping?")
while opcion_incorrecta == 1:
print("1 Si")
print("2 No\n")
proceder = input('Digite el número de opción seguido de la tecla Enter: ')
if proceder == "1":
opcion_incorrecta = 0
try:
print("Ejecutando scrapping de Instagram...")
exec(compile(open("inst2.py","rb").read(),"inst2.py","exec"))
except:
pass
elif proceder == "2":
opcion_incorrecta = 0
pass
else:
print("Ingrese una opción correcta")
#Borrar perfiles encontrados de la lista
flename = 'facebook_target_aux.txt'#Archivo de respuesta
with open(flename, 'w') as f:
f.write("")
print("Facebok Scrapping terminado")
Código de «inst2.py»
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import requests, pickle
import time
import sys
import argparse
import ast
from openpyxl import Workbook
import html as html_library
from scrapingML.scrapingML import *
#-------------------------------------------------------------------------
#-----------------------Configuraciones de login--------------------------
filename = open('config.json')
config = filename.read()
config = ast.literal_eval(config)
user = config['i_user']
password = config['i_pass']
#----------------------------------------------------------------------------
#-------------------------------LOGIN----------------------------------------
if config['i_autenticar']=='si' and config['autenticar']=='si':
session = i_login(user,password)
i_save_session(session)
elif config['i_autenticar']=='no':
session = i_retrieve_session()
#----------------------------------------------------------------------------
#-------------------SCRAPPING DE INFORMACIÓN DE USUARIOS---------------------
print('SCRAPPING INFORMACIÓN DE USUARIO')
#Lectura de los perfiles objetivo del archivo txt
archivo = open('facebook_target_aux.txt',"r")
arch = archivo.read()
if len(arch)==0:
target = open("instagram_target.txt", "r")
urls = []
for line in target:
urls.append(line.strip())
elif len(arch)>0:
archivo = open("facebook_target_aux.txt", "r")
urls = []
for line in archivo:
urls.append(line.strip())
archivo = open("facebook_target_aux.txt", "w")
archivo.write("")
#Para todos los usuarios
for url_user in urls:
print('Scrapping usuario: %s'%url_user)
r3 = session.get(url_user)
print(r3.status_code, r3.url)
for resp in r3.history:
print (resp.status_code, resp.url)
#Archivo de respuesta al perfil del OBJETIVO
flename = 'Instagram_user.html'
with open(flename, 'wb') as f:
f.write(r3.content)
html = r3.text
html = bytes(html, "utf-8").decode("unicode_escape")
info = {}
#Para el nombre:
try:
localizador = html.find('<title>')
nombre_usuario = html[localizador+8:].partition('(')[0]
info['nombre'] = nombre_usuario
except:
pass
#Para la página web:
try:
nombre = html.split('external_url":"')[1].split('"')[0]
info["web"] = nombre
except:
pass
#Para la biografía:
try:
nombre = html.partition('"user":{"biography":"')[2].partition('","')[0]
info["biografia"] = nombre
except:
pass
#Para el número de fotos:
try:
nombre = html.partition('Posts -')[0][::-1].partition(',')[0][::-1]
info["numero_fotos"] = nombre
except:
pass
print(info)
#-----------------------------------------------------------------------------
#------------------------Búsqueda de otras redes------------------------------
if html.find('www.facebook.com/') != -1:
print("Se ha encontrado un perfil de facebook")
try:
url_facebook = html.split('www.facebook.com/')[1].split('"')[0]
url_facebook = 'https://www.facebook.com/'+url_facebook
#Archivo de respuesta al login
flename = 'instagram_target_aux.txt'
with open(flename, 'a+') as f:
f.write(url_facebook+'\n')
print("Almacenando perfil encontrado en instagram_target_aux.txt ...")
except:
print('Error almacenando perfil encontrado')
# ----------------------------------------------------------------------------
# ---------------------------SCRAPPING FOTOS----------------------------------
print('SCRAPPING: FOTOS ')
#Obteniendo lista de fotos primera página
lista_fotos_total = []
def lista_fotos(html):
cont = 0
lista = html.split('shortcode":"')
lista_fotos = []
for elemento in lista:
if cont != 0:
lista_fotos.append(elemento.split('"')[0])
cont = cont +1
return lista_fotos
lista_fotos_total = lista_fotos(html)
#Obteniendo todas las demás fotos
conta = 0
while r3.text.find('end_cursor":"') != -1:
conta = conta +1
print("Obteneindo p+agina: "+str(conta))
end_cursor = html.split('end_cursor":"')[1].split('"')[0]
try:
id_query = r3.text.split('profilePage_')[1].split('"')[0]
except:
id_query = ''
parametros = {
'query_hash':'f2405b236d85e8296cf30347c9f08c2a',
'variables':'{"id":"'+id_query+'","first":12,"after":"'+end_cursor+'"}'
}
time.sleep(5)
r3 = session.get('https://www.instagram.com/graphql/query/',params=parametros)
html = r3.text
#Archivo de respuesta al perfil del OBJETIVO
flename = 'Instagram_masFotos.html'
with open(flename, 'wb') as f:
f.write(r3.content)
#Añadir en lista total de fotos
lista_fotos_total = lista_fotos_total + lista_fotos(r3.text)
#Datos de fotos
def datos_fotos(url):
r4 = session.get(url)
print(r4.status_code, r4.url)
#Archivo de respuesta al perfil del OBJETIVO
flename = 'Instagram_infoFoto.html'
with open(flename, 'wb') as f:
f.write(r4.content)
time.sleep(5)
html = r4.text
html = bytes(html, "utf-8").decode("unicode_escape")
#Localzación de la foto:
try:
localizacion = html.split('Place","name":"')[1].split('"')[0]
except:
localizacion = ""
#Descripción de la foto
try:
descripcion = html.split('<title>')[1].split(':')[1][2::].split('<')[0][0:-2]
except:
descripcion = ""
return descripcion,localizacion
fotos = {}
cont = 0
for elemento in lista_fotos_total:
cont = cont +1
print("Foto %d"%cont)
url = 'http://www.instagram.com/p/'+elemento
fotos['foto%d'%cont]= {'url':url}
time.sleep(5)
try:
descripcion, localizacion = datos_fotos(url)
except:
print('Acceso denegado')
fotos['foto%d'%cont]['descripcion'] = descripcion
fotos['foto%d'%cont]['localizacion'] = localizacion
print(fotos['foto%d'%cont])
print(fotos)
#----------------------------------------------------------------------------
#--------------------------EXPORTACIÓN A EXCEL-------------------------------
print('GENERANDO ARCHIVO')
wb = Workbook()
ws1 = wb.active
ws1.title='Datos'
ws1['A1'] = 'URL'
ws1['A2'] = 'nombre'
ws1['A3'] = 'web'
ws1['A4'] = 'biografia'
ws1['A5'] = 'numero_fotos'
ws1['B1'] = url_user
ws1['B2'] = info['nombre']
ws1['B3'] = info['web']
ws1['B4'] = info['biografia']
ws1['B5'] = info['numero_fotos']
ws2 = wb.create_sheet('fotos')
ws2['A1'] = 'URL'
ws2['B1'] = 'DESCRIPCION'
ws2['C1'] = 'LOCALIZACION'
for num in range(1, len(fotos)+1):
fila = num +1
ws2['A%d'%fila] = fotos['foto%d'%num]['url']
ws2['B%d'%fila] = fotos['foto%d'%num]['descripcion']
ws2['C%d'%fila] = fotos['foto%d'%num]['localizacion']
wb.save('instagram_%s.xlsx'%nombre_usuario)
# ------------------------------------------------------------------------
# --------------------------Scrapping de redes encontradas----------------
#Lectura de los perfiles objetivo del archivo txt
archivo = open('instagram_target_aux.txt',"r")
arch = archivo.read()
if len(arch)==0:
pass
elif len(arch)>0:
opcion_incorrecta =1
print("Se ha encontrado un perfil de facebook, ¿desea ejecutar Facebook Scrapping?")
while opcion_incorrecta == 1:
print("1 Si")
print("2 No\n")
proceder = input('Digite el número de opción seguido de la tecla Enter: ')
if proceder == "1":
opcion_incorrecta = 0
try:
print("Ejecutando scrapping de Facebook...")
exec(compile(open("fb2.py","rb").read(),"fb2.py","exec"))
except:
pass
elif proceder == "2":
print("Continuando")
opcion_incorrecta = 0
pass
else:
print("Ingrese una opción correcta")
flename = 'instagram_target_aux.txt'#Archivo de respuesta
with open(flename, 'w') as f:
f.write("")
print('Instagram Scrapping terminado')
Código de «linkedin.py»
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import requests, pickle
import time
import sys
import argparse
import json
import ast
from openpyxl import Workbook
import html as html_library
from scrapingML.scrapingML import *
#-------------------------------------------------------------------------
#-----------------------Configuraciones de login--------------------------
filename = open('config.json')
config = filename.read()
config = ast.literal_eval(config)
user = config['l_user']
password = config['l_pass']
print(config['l_user'])
print(config['l_pass'])
#----------------------------------------------------------------------------
#-------------------------------LOGIN----------------------------------------
if config['l_autenticar']=='si' and config['autenticar']=='si':
session = li_login(user,password)
li_save_session(session)
elif config['l_autenticar']=='no':
session = li_retrieve_session()
#----------------------------------------------------------------------------
#-------------------SCRAPPING DE INFORMACIÓN DE USUARIOS---------------------
print("SCRAPPING DE USUARIOS")
target = open("linkedin_target.txt", "r")
urls = []
for line in target:
urls.append(line.strip())
for url_user in urls:
print("Perfil: "+url_user)
cookies = ""
for name,value in session.cookies.items():
cookies = cookies + name +'=' +value+';'
session.headers.update({'Host': 'www.linkedin.com',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:68.0) Gecko/20100101 Firefox/68.0',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'es-EC,en-US;q=0.7,en;q=0.3',
'Accept-Encoding': 'gzip, deflate, br',
'Referer': 'https://www.linkedin.com/login?trk=guest_homepage-basic_nav-header-signin',
'Content-Type': 'application/x-www-form-urlencoded',
# 'Content-Length': '4697',
'Connection': 'keep-alive',
'Cookie': cookies,
'Upgrade-Insecure-Requests': '1',
'TE': 'Trailers'
})
time.sleep(5)
r3 = session.get(url_user)
if r3.status_code != 200:
print("No se puede acceder al perfil")
continue
print('\n')
print(r3.status_code, r3.url)
for resp in r3.history:
print (resp.status_code, resp.url)
#Archivo de respuesta
flename = 'Linkedin_user.html'
with open(flename, 'wb') as f:
f.write(r3.content)
html = r3.text.encode('latin1')
html = html.decode('utf-8')
info ={}
#Para el Nombre:
try:
nombre_usuario = html.split('"data":{"firstName":"')[1].split('&')[0]
info['nombre'] = nombre_usuario
except:
nombre_usuario = 'desconocido'
info['nombre'] = ''
#Para el Apellido
try:
html_1 = html.split('"data":{"firstName":"')[1]
nombre = html_1.split('lastName":"')[1].split('&')[0]
info['apellido'] = nombre
except:
info['apellido'] = ''
#Para la Ocupación:
try:
nombre = html_1.split('occupation":"')[1].split('&')[0]
info['ocupacion'] = nombre
except:
info['ocupacion'] = ''
#PARA LA EXPERIENCIA:
try:
experiencia = {}
experiencia[1] = {}
empresa = html.split('companyName":"')
cargo = html.split('","title":"')
counter = 1
empresa_1 = empresa[0][len(empresa[0])-1000:len(empresa[0])]
experiencia[1]['fecha_inicio'] = empresa_1.split('dateRange":{"start":{"')[1].split(',"$type')[0].replace('"','')
try:
experiencia[1]['fecha_terminacion'] = 'hasta: ' + empresa_1.split('"end":{"')[1].split(',"$type')[0].replace('"','')
except:
experiencia[1]['fecha_terminacion'] = 'hasta: actualidad'
for counter in range(1,round(len(cargo))):
experiencia[counter+1] = {}
experiencia[counter]['empresa'] = empresa[counter].split('&')[0]
experiencia[counter]['cargo'] = cargo[counter].split('&')[0]
experiencia[counter+1]['fecha_inicio'] = empresa[counter].split('dateRange":{"start":{"')[1].split(',"$type')[0].replace('"','')
experiencia[counter+1]['fecha_terminacion'] = empresa[counter].split('"end":{"')[1].split(',"$type')[0].replace('"','')
except:
pass
del experiencia[len(experiencia)]
#PARA LA EDUCACIÓN:
educacion = {}
try:
institucion = html.split('"schoolName":"')
counter = 1
for a in institucion:
educacion[counter] = {}
educacion[counter]['institucion'] = institucion[counter].split('&')[0]
counter = counter + 1
except:
pass
#Para la el grado obtenido:
try:
# info['grado'] = ''
grado = html.split('"degreeName":"')
counter = 1
for a in institucion:
educacion[counter]['grado'] = grado[counter].split('&')[0]
counter = counter + 1
except:
educacion[counter]['grado'] = ''
#Para las fechas de inicio de estudios estudio:
try:
counter = 0
for a in institucion:
fechas = institucion[counter].split('"start":{"year":')[1]
educacion[counter+1]['estudio_fecha_inicial'] = fechas.split(',')[0]
counter = counter + 1
except:
pass
#Para las fechas de fin de estudios estudio:
try:
counter = 0
for a in institucion:
fechas = institucion[counter].split('"end":{"year":')[1]
educacion[counter+1]['estudio_fecha_final'] = fechas.split(',')[0]
counter = counter + 1
except:
pass
del educacion[len(educacion)]
#PARA LAS LICENCIAS Y CERTIFICACIONES
try:
certificaciones = {}
certificaciones[1] = {}
html_1 = html.split('"urn:li:fsd_profileCertification:',1)[1].split('"schoolName":"')[0]
nombre = html_1.split(',"name":"')
counter = 1
certificaciones_1 = nombre[0][len(nombre[0])-1000:len(nombre[0])]
try:
certificaciones[1]['fecha_inicio'] = certificaciones_1.split('dateRange":{"start":{"')[1].split(',"$type')[0].replace('"','')
except:
certificaciones[1]['fecha_inicio'] = 'Sin registro'
try:
certificaciones[1]['fecha_terminacion'] = certificaciones_1.split('"end":{"')[1].split(',"$type')[0].replace('"','')
except:
certificaciones[1]['fecha_terminacion'] = 'sin vencimiento'
for a in range(1,len(nombre)):
certificaciones[counter+1] = {}
certificaciones[counter]['nombre'] = nombre[counter].split('&')[0]
try:
institucion = nombre[counter].split('"authority":"')[1]
certificaciones[counter]['institucion'] = institucion.split('&')[0]
except:
certificaciones[counter]['institucion'] = ''
certificaciones[counter+1]['fecha_inicio'] = empresa[counter].split('dateRange":{"start":{"')[1].split(',"$type')[0].replace('"','')
certificaciones[counter+1]['fecha_terminacion'] = empresa[counter].split('"end":{"')[1].split(',"$type')[0].replace('"','')
counter = counter+1
except:
pass
del certificaciones[len(certificaciones)]
print(info)
#----------------------------------------------------------------------------
#--------------------------EXPORTACIÓN A EXCEL-------------------------------
print('GENERANDO ARCHIVO')
wb = Workbook()
ws1 = wb.active
ws1.title='Datos'
ws1['A1'] = 'URL'
ws1['A2'] = 'nombre'
ws1['A3'] = 'apellido'
ws1['A4'] = 'ocupacion'
ws1['A5'] = 'Experiencia'
ws1['B1'] = url_user
ws1['B2'] = info['nombre']
ws1['B3'] = info['apellido']
ws1['B4'] = info['ocupacion']
fila = 5
for num in range(1, len(experiencia)+1):
fila = fila + 1
ws1['A%d'%fila] = experiencia[num]['cargo']
ws1['B%d'%fila] = experiencia[num]['empresa']
ws1['C%d'%fila] = 'Expedición: ' + experiencia[num]['fecha_inicio'] + '; Vence: ' +experiencia[num]['fecha_terminacion']
fila = fila + 1
ws1['A%d'%fila] = 'Educación'
for num in range(1, len(educacion)+1):
fila = fila + 1
ws1['A%d'%fila] = educacion[num]['grado']
ws1['B%d'%fila] = educacion[num]['institucion']
ws1['C%d'%fila] = 'Expedición: ' + educacion[num]['estudio_fecha_inicial'] + '; Vence: ' +educacion[num]['estudio_fecha_final']
fila = fila + 1
ws1['A%d'%fila] = 'Licencias y certificaciones'
for num in range(1, len(certificaciones)+1):
fila = fila + 1
ws1['A%d'%fila] = certificaciones[num]['nombre']
ws1['B%d'%fila] = certificaciones[num]['institucion']
ws1['C%d'%fila] = 'Expedición: ' + certificaciones[num]['fecha_inicio'] + '; Vence: ' +certificaciones[num]['fecha_terminacion']
wb.save('linkedin_%s.xlsx'%nombre_usuario)
Dejar una contestacion