Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
179 changes: 179 additions & 0 deletions modules/jinritoutiaofinder.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
from __future__ import print_function

import os
import sys
import traceback
from time import sleep

from bs4 import BeautifulSoup
from pyvirtualdisplay import Display
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.firefox.options import Options


class Jinritoutiaofinder(object):
timeout = 10

def __init__(self, showbrowser):
if sys.platform == "darwin":
display = Display(visible=0, size=(1600, 1024))
display.start()
opts = Options()
if not showbrowser:
os.environ['MOZ_HEADLESS'] = '1'
opts.headless = True
else:
opts.headless = False
firefoxprofile = webdriver.FirefoxProfile()
firefoxprofile.set_preference("permissions.default.desktop-notification", 1)
firefoxprofile.set_preference("dom.webnotifications.enabled", 1)
firefoxprofile.set_preference("dom.push.enabled", 1)
self.driver = webdriver.Firefox(firefox_profile=firefoxprofile, options=opts)

self.driver.implicitly_wait(15)
self.driver.delete_all_cookies()

def doLogin(self, username, password):
try:
self.driver.get("https://sso.toutiao.com/login/")
self.driver.execute_script('localStorage.clear();')
sleep(3)

print("\n[+] Jinritoutiao Login Page loaded successfully [+]")

# 切换到密码登录
try:
password_login_btn = self.driver.find_element_by_xpath("//div[contains(text(), '密码登录')]")
password_login_btn.click()
sleep(2)
except:
print("[-] Could not find password login button [-]")

# 输入用户名
try:
username_field = self.driver.find_element_by_xpath("//input[@name='username']")
username_field.send_keys(username)
sleep(1)
except:
print("[-] Could not find username field [-]")
traceback.print_exc()
return False

# 输入密码
try:
password_field = self.driver.find_element_by_xpath("//input[@name='password']")
password_field.send_keys(password)
sleep(1)
except:
print("[-] Could not find password field [-]")
traceback.print_exc()
return False

# 点击登录按钮
try:
login_btn = self.driver.find_element_by_xpath("//button[contains(text(), '登录')]")
login_btn.click()
sleep(5)
except:
print("[-] Could not find login button [-]")
traceback.print_exc()
return False

# 检查登录是否成功
if "toutiao.com" in self.driver.current_url:
print("[+] Jinritoutiao Login Success [+]\n")
return True
else:
print("[-] Jinritoutiao Login Failed [-]\n")
return False

except Exception as e:
print("[-] Error during Jinritoutiao login: {}".format(e))
traceback.print_exc()
return False

def getJinritoutiaoProfiles(self, first_name, last_name):
try:
# 搜索用户
url = "https://so.toutiao.com/search?keyword={}+{}".format(first_name, last_name)
self.driver.get(url)
sleep(3)

searchresponse = self.driver.page_source.encode('utf-8')
soupParser = BeautifulSoup(searchresponse, 'html.parser')
picturelist = []

# 查找用户个人资料
# 注意:今日头条的HTML结构可能会变化,需要根据实际情况调整
for element in soupParser.find_all('div', {'class': 'user-info'}):
try:
link = element.find('a')['href']
if not link.startswith("http"):
link = "https://www.toutiao.com" + link

# 获取头像
img_element = element.find('img')
if img_element:
profilepic = img_element['src']
picturelist.append([link, profilepic, 1.0])

except Exception as e:
continue

return picturelist

except Exception as e:
print('[-] Error on line {}: {}'.format(sys.exc_info()[-1].tb_lineno, e))
return []

def sendFriendRequest(self, profile_link):
try:
self.driver.get(profile_link)
sleep(3)

# 查找并点击关注按钮
# 注意:按钮的类名可能会变化
follow_btn = self.driver.find_element_by_xpath("//button[contains(text(), '关注')]")
follow_btn.click()
sleep(2)

print("[+] Friend request sent successfully to {}".format(profile_link))
return True

except Exception as e:
print("[-] Error sending friend request: {}".format(e))
traceback.print_exc()
return False

def sendMessage(self, profile_link, message):
try:
self.driver.get(profile_link)
sleep(3)

# 查找并点击消息按钮
# 注意:按钮的类名可能会变化
message_btn = self.driver.find_element_by_xpath("//button[contains(text(), '发消息')]")
message_btn.click()
sleep(2)

# 输入消息
message_field = self.driver.find_element_by_xpath("//textarea[@placeholder='请输入消息']")
message_field.send_keys(message)
sleep(1)

# 发送消息
send_btn = self.driver.find_element_by_xpath("//button[contains(text(), '发送')]")
send_btn.click()
sleep(2)

print("[+] Message sent successfully to {}".format(profile_link))
return True

except Exception as e:
print("[-] Error sending message: {}".format(e))
traceback.print_exc()
return False

def kill(self):
self.driver.quit()
114 changes: 110 additions & 4 deletions social_mapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from modules import twitterfinder
from modules import vkontaktefinder
from modules import weibofinder
from modules import jinritoutiaofinder

assert sys.version_info >= (3,), "Only Python 3 is currently supported."

Expand Down Expand Up @@ -65,6 +66,10 @@
global pinterest_password
pinterest_username = ""
pinterest_password = ""
global jinritoutiao_username
global jinritoutiao_password
jinritoutiao_username = ""
jinritoutiao_password = ""

global showbrowser

Expand Down Expand Up @@ -94,6 +99,8 @@ class Person(object):
doubanimage = ""
pinterest = ""
pinterestimage = ""
jinritoutiao = ""
jinritoutiaoimage = ""

def __init__(self, first_name, last_name, full_name, person_image):
self.first_name = first_name
Expand All @@ -113,6 +120,88 @@ def __init__(self, full_name, profile_link, image_link):
self.image_link = image_link


def fill_jinritoutiao(peoplelist):
JinritoutiaofinderObject = jinritoutiaofinder.Jinritoutiaofinder(showbrowser)
JinritoutiaofinderObject.doLogin(jinritoutiao_username, jinritoutiao_password)
if args.waitafterlogin:
input("Press Enter to continue after verifying you are logged in...")

count = 1
ammount = len(peoplelist)
for person in peoplelist:
if args.vv == True or args.debug == True:
print("Jinritoutiao Check %i/%i : %s" % (count, ammount, person.full_name))
else:
sys.stdout.write(
"\rJinritoutiao Check %i/%i : %s " % (count, ammount, person.full_name))
sys.stdout.flush()
count = count + 1

if person.person_image:
try:
target_image = face_recognition.load_image_file(person.person_image)
target_encoding = face_recognition.face_encodings(target_image)[0]
profilelist = JinritoutiaofinderObject.getJinritoutiaoProfiles(person.first_name, person.last_name)
if args.debug == True:
print(profilelist)
except:
continue
else:
continue

early_break = False
updatedlist = []
for profilelink, profilepic, distance in profilelist:
try:
os.remove("potential_target_image.jpg")
except:
pass
if early_break:
break
image_link = profilepic

cookies = JinritoutiaofinderObject.getCookies()
if image_link:
try:
headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/602.2.14 (KHTML, like Gecko) Version/10.0.1 Safari/602.2.14'}
response = requests.get(image_link, cookies=cookies, headers=headers, stream=True)
with open('potential_target_image.jpg', 'wb') as out_file:
response.raw.decode_content = True
shutil.copyfileobj(response.raw, out_file)
del response
potential_target_image = face_recognition.load_image_file("potential_target_image.jpg")
try:
potential_target_encoding = face_recognition.face_encodings(potential_target_image)[0]
except:
continue
results = face_recognition.face_distance([target_encoding], potential_target_encoding)
for result in results:
if args.mode == "fast":
if result < threshold:
person.jinritoutiao = encoding.smart_str(profilelink, encoding='ascii', errors='ignore')
person.jinritoutiaoimage = encoding.smart_str(image_link, encoding='ascii', errors='ignore')
if args.vv == True:
print("\tMatch found: " + person.full_name)
print("\tJinritoutiao: " + person.jinritoutiao)
early_break = True
break
else:
updatedlist.append([result, profilelink, image_link])
except:
continue

if not args.mode == "fast":
if len(updatedlist) > 0:
updatedlist.sort()
if updatedlist[0][0] < threshold:
person.jinritoutiao = encoding.smart_str(updatedlist[0][1], encoding='ascii', errors='ignore')
person.jinritoutiaoimage = encoding.smart_str(updatedlist[0][2], encoding='ascii', errors='ignore')
if args.vv == True:
print("\tMatch found: " + person.full_name)
print("\tJinritoutiao: " + person.jinritoutiao)

JinritoutiaofinderObject.kill()
def fill_facebook(peoplelist):
FacebookfinderObject = facebookfinder.Facebookfinder(showbrowser)
FacebookfinderObject.doLogin(facebook_username, facebook_password)
Expand Down Expand Up @@ -1420,6 +1509,13 @@ def loadPage(client, url, data=None):
doubanwritestring = '"%s","%s","%s","%s","%s","%s"\n' % (
person.first_name, person.last_name, person.full_name, email, person.douban, person.doubanimage)
filewriterdouban.write(doubanwritestring)
if args.a == True or args.tt == True or args.format == "socialmapper":
writestring = writestring + '"%s",' % (person.jinritoutiao)
if person.jinritoutiao != "" and args.email is not None:
if email != "Error":
jinritoutiaowritestring = '"%s","%s","%s","%s","%s","%s"\n' % (
person.first_name, person.last_name, person.full_name, email, person.jinritoutiao, person.jinritoutiaoimage)
filewriterjinritoutiao.write(jinritoutiaowritestring)

writestring = writestring[:-1]
filewriter.write(writestring)
Expand All @@ -1444,6 +1540,8 @@ def loadPage(client, url, data=None):
terminalstring = terminalstring + "\tWeibo: " + person.weibo + "\n"
if person.douban != "":
terminalstring = terminalstring + "\tDouban: " + person.douban + "\n"
if person.jinritoutiao != "":
terminalstring = terminalstring + "\tJinritoutiao: " + person.jinritoutiao + "\n"
if terminalstring != "":
print(person.full_name + "\n" + terminalstring)

Expand Down Expand Up @@ -1493,6 +1591,11 @@ def loadPage(client, url, data=None):
filewriterdouban.close()
except:
pass
try:
if filewriterjinritoutiao:
filewriterjinritoutiao.close()
except:
pass

# Code for generating HTML file
htmloutputfilename = "SM-Results/" + args.input.replace("\"", "").replace("/", "-") + "-social-mapper.html"
Expand Down Expand Up @@ -1633,10 +1736,10 @@ def loadPage(client, url, data=None):
</style>
"""
foot = "</table></center>"
header = """<center><table id=\"employees\">
header = """<center><table id="employees">
<tr>
<th rowspan=\"2\">Photo</th>
<th rowspan=\"2\">Name</th>
<th rowspan="2">Photo</th>
<th rowspan="2">Name</th>
<th>LinkedIn</th>
<th>Facebook</th>
<th>Twitter</th>
Expand All @@ -1647,6 +1750,7 @@ def loadPage(client, url, data=None):
<th>VKontakte</th>
<th>Weibo</th>
<th>Douban</th>
<th>Jinritoutiao</th>
</tr>
"""
filewriter.write(css)
Expand All @@ -1671,13 +1775,15 @@ def loadPage(client, url, data=None):
"<td class=\"hasTooltipcenterright\"><a href=\"%s\"><img src=\"%s\" onerror=\"this.style.display=\'none\'\" width=auto height=auto style=\"max-width:100px; max-height:100px;\"><span>VKontakte:<br>%s</span></a></td>" \
"<td class=\"hasTooltipright\"><a href=\"%s\"><img src=\"%s\" onerror=\"this.style.display=\'none\'\" width=auto height=auto style=\"max-width:100px; max-height:100px;\"><span>Weibo:<br>%s</span></a></td>" \
"<td class=\"hasTooltipfarright\"><a href=\"%s\"><img src=\"%s\" onerror=\"this.style.display=\'none\'\" width=auto height=auto style=\"max-width:100px; max-height:100px;\"><span>Douban:<br>%s</span></a></td>" \
"<td class=\"hasTooltipfarright\"><a href=\"%s\"><img src=\"%s\" onerror=\"this.style.display=\'none\'\" width=auto height=auto style=\"max-width:100px; max-height:100px;\"><span>Jinritoutiao:<br>%s</span></a></td>" \
"</tr>" \
"</tbody>" % (
local_image_link, local_image_link, person.full_name, person.linkedin, person.linkedinimage,
person.linkedin, person.facebook, person.facebookcdnimage, person.facebook, person.twitter,
person.twitterimage, person.twitter, person.instagram, person.instagramimage, person.instagram,
person.pinterest, person.pinterestimage, person.pinterest, person.vk, person.vkimage, person.vk,
person.weibo, person.weiboimage, person.weibo, person.douban, person.doubanimage, person.douban)
person.weibo, person.weiboimage, person.weibo, person.douban, person.doubanimage, person.douban,
person.jinritoutiao, person.jinritoutiaoimage, person.jinritoutiao)
filewriter.write(body)

filewriter.write(foot)
Expand Down