Web Scraping de redes sociales con Python

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('&quot;data&quot;:{&quot;firstName&quot;:&quot;')[1].split('&')[0]
        info['nombre'] = nombre_usuario
    except:
        nombre_usuario = 'desconocido'
        info['nombre'] = ''
    #Para el Apellido
    try:
        html_1 = html.split('&quot;data&quot;:{&quot;firstName&quot;:&quot;')[1]
        nombre = html_1.split('lastName&quot;:&quot;')[1].split('&')[0]
        info['apellido'] = nombre
    except:
        info['apellido'] = ''
    #Para la Ocupación:
    try:
        nombre = html_1.split('occupation&quot;:&quot;')[1].split('&')[0]
        info['ocupacion'] = nombre
    except:
        info['ocupacion'] = ''
    #PARA LA EXPERIENCIA:
    try:
        experiencia = {}
        experiencia[1] = {}
        empresa = html.split('companyName&quot;:&quot;')
        cargo = html.split('&quot;,&quot;title&quot;:&quot;')
        counter = 1
        empresa_1 = empresa[0][len(empresa[0])-1000:len(empresa[0])]
        experiencia[1]['fecha_inicio'] = empresa_1.split('dateRange&quot;:{&quot;start&quot;:{&quot;')[1].split(',&quot;$type')[0].replace('&quot;','')
        try:
            experiencia[1]['fecha_terminacion'] = 'hasta: ' + empresa_1.split('&quot;end&quot;:{&quot;')[1].split(',&quot;$type')[0].replace('&quot;','')
        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&quot;:{&quot;start&quot;:{&quot;')[1].split(',&quot;$type')[0].replace('&quot;','') 
            experiencia[counter+1]['fecha_terminacion'] = empresa[counter].split('&quot;end&quot;:{&quot;')[1].split(',&quot;$type')[0].replace('&quot;','')
    except:
        pass
    del experiencia[len(experiencia)]
    #PARA LA EDUCACIÓN:
    educacion = {}
    try:
        institucion = html.split('&quot;schoolName&quot;:&quot;')
        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('&quot;degreeName&quot;:&quot;')
        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('&quot;start&quot;:{&quot;year&quot;:')[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('&quot;end&quot;:{&quot;year&quot;:')[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('&quot;urn:li:fsd_profileCertification:',1)[1].split('&quot;schoolName&quot;:&quot;')[0]
        nombre = html_1.split(',&quot;name&quot;:&quot;')
        counter = 1
        certificaciones_1 = nombre[0][len(nombre[0])-1000:len(nombre[0])]
        try:
            certificaciones[1]['fecha_inicio'] = certificaciones_1.split('dateRange&quot;:{&quot;start&quot;:{&quot;')[1].split(',&quot;$type')[0].replace('&quot;','')
        except:
            certificaciones[1]['fecha_inicio'] = 'Sin registro'
        try:
            certificaciones[1]['fecha_terminacion'] = certificaciones_1.split('&quot;end&quot;:{&quot;')[1].split(',&quot;$type')[0].replace('&quot;','')
        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('&quot;authority&quot;:&quot;')[1]
                certificaciones[counter]['institucion'] = institucion.split('&')[0]
            except:
                certificaciones[counter]['institucion'] = ''
            certificaciones[counter+1]['fecha_inicio'] = empresa[counter].split('dateRange&quot;:{&quot;start&quot;:{&quot;')[1].split(',&quot;$type')[0].replace('&quot;','') 
            certificaciones[counter+1]['fecha_terminacion'] = empresa[counter].split('&quot;end&quot;:{&quot;')[1].split(',&quot;$type')[0].replace('&quot;','')    
            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)

Sé el primero en comentar

Dejar una contestacion

Tu dirección de correo no será publicada.


*