网站首页 包含标签 Python 的所有文章

  • Python 中为什么不建议使用 time.sleep 实现定时功能?

    有时候,我们想实现一个非常简单的定时功能,例如:让一个程序每天早上 8 点调用某个函数 但我们又不想安装任何第三方库,也不会使用 crontab 或者任务计划功能,就想使用纯 Python 来实现 可能有同学会这样写代码: import time import datetime def run():     print('我是需要被每天调用的函数') def schedule():     target_time = datetime.time(8, 0, 0)     today = datetime.date.today()     target_date = today + datetime.timedelta(days=1)     target_datetime = datetime.datetime.combine(target_date, target_time)     now = datetime.datetime.now()     delta = (target_datetime - now).total_seconds()     time.sleep(delta)     run()     while True:         time.sleep(24 * 3600)         run() if __name__ == '__main__':     schedule() 这段程序,首先计算出现在距离明天早上 8 点相差的秒数;睡眠这么多秒以后,第一次运行目标函数,然后进入一个死循环,每隔 86400 秒,程序调用一次 run 函数 这个程序初看起来,似乎没有什么问题 但如果你每天观察它的运行时间,你会发现随着时间的推移,时间会越来越不准确 这是因为,run 函数不是一瞬间就运行完成的。它运行也会消耗时间 假设程序第一次运行 run 函数的时候,确实刚刚好是 8:00,run 函数运行了 2秒;那么,程序睡眠 86400 秒以后,时间实际上是 8:00:02.从第二天开始,每天晚 2 秒钟。一个月就会晚一分钟 但实际上,我们如果付出一点点微不足道的代价,我们就可以防止这种误差的发生,并且程序代码会变得更简单: import time import datetime def run():     print('我是需要被每天调用的函数') def schedule():     last_run = None     while True:         now = datetime.datetime.now()         if now.strftime('%H:%M') == '08:00' and last_run != now.date():             run()             last_run = now.date()         time.sleep(1) if __name__ == '__main__':     schedule() 程序在一个死循环中,每秒做一次检查,如果当前的时分正好是 08:00,并且上一次运行不是今天,那么就调用 run 函数,并把上一次运行的时间设置为今天。否则,就睡眠 1 秒钟 这样做,相当于每秒都会校对时间,从而避免了长时间运行导致的时间误差。虽然看起来这个死循环会非常消耗 CPU,但只要你算一下,实际上它只不过每天循环 86400 次而已。这个次数并不多 但无论如何,专业的事情应该交由专业的工具来做;time.sleep 用来设置周期性的时间间隔可以,但它实际上不适合用来做定时任务 因为一个支持定时任务的库,例如:Python 的schedule或者APScheduler,他们在确保定时时间准确上,做了很多工作。还有一些库甚至用到了时间轮这样的数据结构来确保时间的准确性。这不是我们简单用两三行 Python 代码就能完成的。 总结 如果能用 crontab 或者任务计划,那么这是最优选择;其次,使用 Python 专用的定时模块;最次,才是使用 time.sleep 来实现 如果不得不用 time.sleep,那么应该尽量缩短检查的间隔,避免长时间睡眠 ...

    2020-12-23 418
  • 如何提高 Python 的运行速度?

    Python 目前得到了众多程序员的喜爱,但是还是遭到一些人的诟病,原由之一就是认为它运行缓慢。 其实某个特定程序(无论使用何种编程语言)的运行速度是快还是慢,在很大程度上取决于编写该程序的开发人员自身素质,以及他们编写优化而高效代码的能力。 Medium 上一位小哥就详细讲了讲如何让 Python 提速 30%,以此证明代码跑得慢不是 Python的问题,而是代码本身的问题。 01时序分析 在开始进行任何优化之前,我们首先需要找出代码的哪些部分使整个程序变慢。有时程序的问题很明显,但是如果你一时不知道问题出在哪里,那么这里有一些可能的选项: 注意:这是我将用于演示的程序,它将进行指数计算 # slow_program.py from decimal import * def exp(x):     getcontext().prec += 2     i, lasts, s, fact, num = 0, 0, 1, 1, 1     while s != lasts:         lasts = s         i += 1         fact *= i         num *= x         s += num / fact     getcontext().prec -= 2     return +s exp(Decimal(150)) exp(Decimal(400)) exp(Decimal(3000)) 最简约的“配置文件” 首先,最简单最偷懒的方法——Unix时间命令。 ~ $ time python3.8 slow_program.py real  0m11,058s user 0m11,050s sys 0m0,008s 如果你只能知道整个程序的运行时间,这样就够了,但通常这还远远不够。 最详细的分析 另外一个指令是cProfile,但是它提供的信息过于详细了。 ~ $ python3.8 -m cProfile -s time slow_program.py          1297 function calls (1272 primitive calls) in 11.081 seconds    Ordered by: internal time    ncalls tottime percall cumtime percall filename:lineno(function)         3   11.079    3.693   11.079    3.693 slow_program.py:4(exp)         1    0.000    0.000    0.002    0.002 {built-in method _imp.create_dynamic}       4/1    0.000    0.000   11.081   11.081 {built-in method builtins.exec}         6    0.000    0.000    0.000    0.000 {built-in method __new__ of type object at 0x9d12c0}         6    0.000    0.000    0.000    0.000 abc.py:132(__new__)        23    0.000    0.000    0.000    0.000 _weakrefset.py:36(__init__)       245    0.000    0.000    0.000    0.000 {built-in method builtins.getattr}         2    0.000    0.000    0.000    0.000 {built-in method marshal.loads}        10    0.000    0.000    0.000    0.000 <frozen importlib._bootstrap_external>:1233(find_spec)       8/4    0.000    0.000    0.000    0.000 abc.py:196(__subclasscheck__)        15    0.000    0.000    0.000    0.000 {built-in method posix.stat}         6    0.000    0.000    0.000    0.000 {built-in method builtins.__build_class__}         1    0.000    0.000    0.000    0.000 __init__.py:357(namedtuple)        48    0.000    0.000    0.000    0.000 <frozen importlib._bootstrap_external>:57(_path_join)        48    0.000    0.000    0.000    0.000 <frozen importlib._bootstrap_external>:59(<listcomp>)         1    0.000    0.000   11.081   11.081 slow_program.py:1(<module>) 在这里,我们使用cProfile模块和time参数运行测试脚本,以便按内部时间(cumtime)对行进行排序。这给了我们很多信息,你在上面看到的行大约是实际输出的10%。由此可见,exp函数是罪魁祸首,现在我们可以更详细地了解时序和性能分析。 时序特定功能 现在我们知道了应当主要关注哪里,我们可能想对运行速度缓慢的函数计时,而不用测量其余的代码。为此,我们可以使用一个简单的装饰器: def timeit_wrapper(func):     @wraps(func)     def wrapper(*args, **kwargs):         start = time.perf_counter() # Alternatively, you can use time.process_time()         func_return_val = func(*args, **kwargs)         end = time.perf_counter()         print('{0:<10}.{1:<8} : {2:<8}'.format(func.__module__, func.__name__, end - start))         return func_return_val     return wrapper 然后可以将此装饰器应用于待测功能,如下所示: @timeit_wrapper def exp(x):     ... print('{0:<10} {1:<8} {2:^8}'.format('module', 'function', 'time')) exp(Decimal(150)) exp(Decimal(400)) exp(Decimal(3000)) 这给出我们如下输出: ~ $ python3.8 slow_program.py module function   time   __main__ .exp      : 0.003267502994276583 __main__ .exp      : 0.038535295985639095 __main__ .exp      : 11.728486061969306 需要考虑的一件事是我们实际想要测量的时间。时间包提供time.perf_counter和time.process_time两个函数。他们的区别在于perf_counter返回的绝对值,包括你的Python程序进程未运行时的时间,因此它可能会受到计算机负载的影响。另一方面,process_time仅返回用户时间(不包括系统时间),这仅是你的过程时间。 02加速吧! 让Python程序运行得更快,这部分会很有趣!我不会展示可以解决你的性能问题的技巧和代码,更多地是关于构想和策略的,这些构想和策略在使用时可能会对性能产生巨大影响,在某些情况下,可以将速度提高30%。 使用内置数据类型 这一点很明显。内置数据类型非常快,尤其是与我们的自定义类型(例如树或链接列表)相比。这主要是因为内置程序是用C实现的,因此在使用Python进行编码时我们的速度实在无法与之匹敌。 使用lru_cache缓存/记忆 我已经在上一篇博客中展示了此内容,但我认为值得用简单的示例来重复它: import functools import time # caching up to 12 different results @functools.lru_cache(maxsize=12) def slow_func(x):     time.sleep(2) # Simulate long computation     return x slow_func(1) # ... waiting for 2 sec before getting result slow_func(1) # already cached - result returned instantaneously! slow_func(3) # ... waiting for 2 sec before getting result 上面的函数使用time.sleep模拟大量计算。第一次使用参数1调用时,它将等待2秒钟,然后才返回结果。再次调用时,结果已经被缓存,因此它将跳过函数的主体并立即返回结果。有关更多实际示例,请参见以前的博客文章。 使用局部变量 这与在每个作用域中查找变量的速度有关,因为它不只是使用局部变量还是全局变量。实际上,即使在函数的局部变量(最快),类级属性(例如self.name——较慢)和全局(例如,导入的函数)如time.time(最慢)之间,查找速度实际上也有所不同。 你可以通过使用看似不必要的分配来提高性能,如下所示: # Example #1 class FastClass:     def do_stuff(self):         temp = self.value # this speeds up lookup in loop         for i in range(10000):             ... # Do something with `temp` here # Example #2 import random def fast_function():     r = random.random     for i in range(10000):         print(r()) # calling `r()` here, is faster than global random.random() 使用函数 这似乎违反直觉,因为调用函数会将更多的东西放到堆栈上,并从函数返回中产生开销,但这与上一点有关。如果仅将整个代码放在一个文件中而不将其放入函数中,则由于全局变量,它的运行速度会慢得多。因此,你可以通过将整个代码包装在main函数中并调用一次来加速代码,如下所示: def main():     ... # All your previously global code main() 不访问属性 可能会使你的程序变慢的另一件事是点运算符(.),它在获得对象属性时被使用。此运算符使用__getattribute__触发字典查找,这会在代码中产生额外的开销。那么,我们如何才能真正避免(限制)使用它呢? # Slow: import re def slow_func():     for i in range(10000):         re.findall(regex, line) # Slow! # Fast: from re import findall def fast_func():     for i in range(10000):         findall(regex, line) # Faster! 当心字符串 使用模数(%s)或.format()进行循环运行时,字符串操作可能会变得非常慢。我们有什么更好的选择?根据雷蒙德·海廷格(Raymond Hettinger)最近的推特,我们唯一应该使用的是f-string,它是最易读,最简洁且最快的方法。根据该推特,这是你可以使用的方法列表——最快到最慢: f'{s} {t}'  # Fast! s + ' ' + t ' '.join((s, t)) '%s %s' % (s, t) '{} {}'.format(s, t) Template('$s $t').substitute(s=s, t=t) # Slow! 生成器本质上并没有更快,因为它们被允许进行延迟计算,从而节省了内存而不是时间。但是,保存的内存可能会导致你的程序实际运行得更快。这是怎么做到的?如果你有一个很大的数据集,而没有使用生成器(迭代器),那么数据可能会溢出CPU L1缓存,这将大大减慢内存中值的查找速度。 在性能方面,非常重要的一点是CPU可以将正在处理的所有数据尽可能地保存在缓存中。你可以观看Raymond Hettingers的视频,他在其中提到了这些问题。 03结论 优化的首要规则是不要优化。但是,如果确实需要,那么我希望上面这些技巧可以帮助你。但是,在优化代码时要小心,因为它可能最终使你的代码难以阅读,因此难以维护,这可能超过优化的好处。 ...

    2020-12-06 361
  • 最全总结!聊聊 Python 发送邮件的几种方式

    1. 前言 邮件,作为最正式规范的沟通方式,在日常办公过程中经常被用到 我们都知道 Python内置了对 SMTP 的支持,可以发送纯文本、富文本、HTML 等格式的邮件 本文将聊聊利用 Python 发送邮件的 3 种方式 2. 准备 以 126 邮箱为例,在编码之前,我们需要开启 SMTP 服务 然后,手动新增一个授权码 其中,账号、授权码和服务器地址用于连接登录邮箱服务器 3. 方式一:smtplib smtplib是 Python 自带的依赖库,可以直接导入使用首先,通过邮箱账号、授权码、邮箱服务器地址初始化一个 SMTP 实例,然后进行连接 def __init__(self):     # 初始化     self.smtp = smtplib.SMTP()     # 连接邮箱服务器地址     self.smtp.connect('smtp.126.com')     # 加入主题和附件,邮件体     self.email_body = MIMEMultipart('mixed')     # 发件人地址及授权码     self.email_from_username = '**@126.com'     self.email_from_password = '授权码' # 登录 self.smtp.login(self.email_from_username, self.email_from_password) 然后,将收件人列表、邮件标题、邮件正文内容、附件路径及附件文件名加入到上面定义的邮件体中 def generate_email_body(self, email_to_list, email_title, email_content, attchment_path, files):     """     组成邮件体     :param email_to_list:收件人列表     :param email_title:邮件标题     :param email_content:邮件正文内容     :param attchment_path:附件的路径     :param files:附件文件名列表     :return:     """     self.email_body['Subject'] = email_title     self.email_body['From'] = self.email_from_username     self.email_body['To'] = ",".join(email_to_list)     for file in files:         file_path = attchment_path + '/' + file         if os.path.isfile(file_path):             # 构建一个附件对象             att = MIMEText(open(file_path, 'rb').read(), 'base64', 'utf-8')             att["Content-Type"] = 'application/octet-stream'             att.add_header("Content-Disposition", "attachment", filename=("gbk", "", file))             self.email_body.attach(att)     text_plain = MIMEText(email_content, 'plain', 'utf-8')     self.email_body.attach(text_plain) 接着,就可以使用 SMTP 实例对象,将邮件发送出去  # 收件人列表 email_to_list = ['收件人1地址','收件人2地址'] # 发送邮件 # 注意:此处必须同时指定发件人与收件人,否则会当作垃圾邮件处理掉 self.smtp.sendmail(self.email_from_username, email_to_list, self.email_body.as_string()) 邮件发送完毕之后,退出服务即可 def exit(self):     """     退出服务     :return:     """     self.smtp.quit() 4. 方式二:zmail Zmail 项目创建目的是,使邮件处理变得更简单 使用 Zmail 发送接收邮件方便快捷,不需要手动添加服务器地址、端口以及适合的协议,可以轻松创建 MIME 对象和头文件 注意:Zmail 仅支持 Python3,不支持 Python2 首先,安装依赖库 # 安装依赖库 pip3 install zmail 然后,使用邮箱账号、授权码创建一个邮箱服务对象 class ZMailObject(object):     def __init__(self):         # 邮箱账号         self.username = '**@126.com'         # 邮箱授权码         self.authorization_code = '授权码'         # 构建一个邮箱服务对象         self.server = zmail.server(self.username, self.authorization_code) 接着,将邮件主题、邮件内容、包含的附件路径加入到一个字典中,组成邮件主体 # 邮件主体 mail_body = {         'subject': '测试报告',         'content_text': '这是一个测试报告',  # 纯文本或者HTML内容         'attachments': ['./attachments/report.png'], } 最后,将调用send_mail()函数,将邮件发送出去即可 # 收件人 # 可以指定一个人,字符串;也可以是多个人,列表 mail_to = "收件人1" # 发送邮件 self.server.send_mail(mail_to, mail_body) 5. 方式三:yagmail yagmail 只需要几行代码,就能实现发送邮件的功能 相比 zmail,yagmail 实现发送邮件的方式更加简洁优雅 首先,安装依赖库 # 安装依赖库 pip3 install yagmail 然后,通过账号、授权码和服务器地址连接邮箱服务器,返回一个服务对象 import yagmail # 连接服务器 # 用户名、授权码、服务器地址 yag_server = yagmail.SMTP(user='**@126.com', password='授权码', host='smtp.126.com') 接着,通过 send() 函数,将邮件发送出去 # 发送对象列表 email_to = ['**@qq.com', ] email_title = '测试报告' email_content = "这是测试报告的具体内容" # 附件列表 email_attachments = ['./attachments/report.png', ] # 发送邮件 yag_server.send(email_to, email_title, email_content, email_attachments) 邮件发送完毕之后,关闭连接即可 # 关闭连接 yag_server.close() 6. 最后 上面总结了 Python 发送邮件的 3 种方式,实际项目中,更推荐使用后两种方式 我已经将文中全部源码上传到后台,关注公众号后回复「 email 」即可获得全部源码 如果你觉得文章还不错,请大家可以 加入我们的交流群,因为这将是我持续输出更多优质文章的最强动力! ...

    2020-07-14 1084
  • 用python编写自动信息收集脚本(三) -ip收集

    本人只是python初学者,本文只适合初学者观看学习。大佬请绕过(或者指出需要改进的地方)!在日常渗透测试过程中我们都知道,在对目标进行渗透之前都是先要信息收集一波。收集到越多的信息往往渗透过程中越顺利,所以信息收集格外重要。而信息收集往往费时间比较多,所以我们想写一个自动信息收集的脚本,但是代码量太大。本文就先从whois信息开始,代码不好的地方。希望大家提出意见! 本次模块配合之前的用python编写自动信息收集脚本一,二使用 import threading #多线程 import requests import time from lxml import etree import re #正则表达式 import csv import telnetlib #建立tcp链接 实现端口扫描 class xxsj(object):     def __init__(self):         global dk #创建全局变量,后面端口扫描用         self.wz = input("请输入您想查询的网站") #接收网站地址         dk = self.wz         self.a = re.sub(r"www.","",self.wz) #正则表达式,匹配www. 然后删除         self.header = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'}     def ip(self):         url='https://dns.aizhan.com/' self.wz '/' # url地址         print("----在获取ip地址----")         response = requests.get(url=url, headers=self.header)         selector = etree.HTML(response.content)         title = "IP地址"         global ab #创建全局 ...

    2020-06-20 574
  • 用python编写自动信息收集脚本(二)网站信息搜集

    本人只是python初学者,本文只适合初学者观看学习。大佬请绕过(或者指出需要改进的地方)!在日常渗透测试过程中我们都知道,在对目标进行渗透之前都是先要信息收集一波。收集到越多的信息往往渗透过程中越顺利,所以信息收集格外重要。而信息收集往往费时间比较多,所以我们想写一个自动信息收集的脚本,但是代码量太大。本文就先从whois信息开始,代码不好的地方。希望大家提出意见! 本次模块配合之前的用python编写自动信息收集脚本(一)使用 def xx(self):     url = 'https://www.aizhan.com/seo/' self.wz     response = requests.get(url=url, headers=self.header)     selector = etree.HTML(response.content)     title = selector.xpath('//*[@id="icp"]/li[1]/text()')[0]   #备案号 获取li[1]下的文本     infor = selector.xpath('//*[@id="icp_icp"]/text()')[0]   #备案信息     a = selector.xpath('//*[@id="icp_company"]/text()')[0]   #公司性质     b = selector.xpath('//*[@id="icp_type"]/text()')[0]    #公司名称     c = 1     for i in range(0, 2):     #写两次  将四个变量两次写人csv文件中         if c == 1:             self.write([title, infor])             c = c 1         else:             self.write([b, a]) ...

    2020-06-20 741
  • 用python编写自动信息收集脚本(一)

    本人只是python初学者,本文只适合初学者观看学习。大佬请绕过(或者指出需要改进的地方)! 在日常渗透测试过程中我们都知道,在对目标进行渗透之前都是先要信息收集一波。收集到越多的信息往往渗透过程中越顺利,所以信息收集格外重要。而信息收集往往费时间比较多,所以我们想写一个自动信息收集的脚本,但是代码量太大。本文就先从whois信息开始,代码不好的地方。希望大家提出意见! import requests from lxml import etree import csv class xxsj(object):     def __init__(self):         self.header = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'}     def whois(self):         wz = input('请输入您想信息收集的网站:')         print("正在whois查询",)         url = 'https://whois.aizhan.com/' wz         response = requests.get(url=url, headers=self.header)         selector = etree.HTML(response.content)         title = selector.xpath('//td[@class="thead"]/text()')         yuming = selector.xpath('//td[2]//text()')         a = len(title)         for i in range(0, a - 1):             title1 = title             yuming1 = yuming             self.write([title1, yuming1])     def write(self,lis):         with open('信息收集.csv', ...

    2020-06-20 988
  • 不懂代码也能爬取数据?试试这几个工具

    前天,有个同学加我微信来咨询我: “毒蜂,我想抓取近期 5000 条新闻数据,但我是文科生,不会写代码,请问该怎么办?” 有问必答,毒蜂对于这位同学的问题,我给安排上。 先说说获取数据的方式:一是利用现成的工具,我们只需懂得如何使用工具就能获取数据,不需要关心工具是怎么实现。打个比方,假如我们在岸上,要去海上某个小岛,岸边有一艘船,我们第一想法是选择坐船过去,而不会想着自己来造一艘船再过去。 第二种是自己针对场景需求做些定制化工具,这就需要有点编程基础。举个例子,我们还是要到海上某个小岛,同时还要求在 30 分钟内将 1 顿货物送到岛上。 因此,前期只是单纯想获取数据,没有什么其他要求的话,优先选择现有工具。 可能是 Python 近来年很火,加上我们会经常看到别人用 Python 来制作网络爬虫抓取数据。从而有一些同学有这样的误区,想从网络上抓取数据就一定要学 Python,一定要去写代码。 其实不然,毒蜂介绍几个能快速获取网上数据的工具。 1.Microsoft Excel 你没有看错,就是 Office 三剑客之一的 Excel。Excel 是一个强大的工具,能抓取数据就是它的功能之一。我以耳机作为关键字,抓取京东的商品列表。 等待几秒后,Excel 会将页面上所有的文字信息抓取到表格中。这种方式确实能抓取到数据,但也会引入一些我们不需要的数据。如果你有更高的需求,可以选择后面几个工具。 2.火车头采集器 火车头是爬虫界的老品牌了,是目前使用人数最多的互联网数据抓取、处理、分析,挖掘软件。它的优势是采集不限网页,不限内容,同时还是分布式采集,效率会高一些。缺点是对小白用户不是很友好,有一定的知识门槛(了解如网页知识、HTTP 协议等方面知识),还需要花些时间熟悉工具操作。 因为有学习门槛,掌握该工具之后,采集数据上限会很高。有时间和精力的同学可以去折腾折腾。 官网地址:http://www.locoy.com/ 3.八爪鱼采集器 八爪鱼采集器是一款非常适合新手的采集器。它具有简单易用的特点,让你能几分钟中就快手上手。八爪鱼提供一些常见抓取网站的模板,使用模板就能快速抓取数据。如果想抓取没有模板的网站,官网也提供非常详细的图文教程和视频教程。 八爪鱼是基于浏览器内核实现可视化抓取数据,所以存在卡顿、采集数据慢的特点。但这瑕不掩瑜,能基本满足新手在短时间抓取数据的场景,比如翻页查询,Ajax 动态加载数据等。 网站:https://www.bazhuayu.com/ 4.GooSeeker 集搜客 集搜客也是一款容易上手的可视化采集数据工具。同样能抓取动态网页,也支持可以抓取手机网站上的数据,还支持抓取在指数图表上悬浮显示的数据。集搜客是以浏览器插件形式抓取数据。虽然具有前面所述的有点,但缺点也有,无法多线程采集数据,出现浏览器卡顿也在所难免。 网站:https://www.gooseeker.com/ 5.Scrapinghub 如果你想抓取国外的网站数据,可以考虑 Scrapinghub。Scrapinghub 是一个基于Python 的 Scrapy 框架的云爬虫平台。Scrapehub 算是市场上非常复杂和强大的网络抓取平台,提供数据抓取的解决方案商。 地址:https://scrapinghub.com/ 6.WebScraper WebScraper 是一款优秀国外的浏览器插件。同样也是一款适合新手抓取数据的可视化工具。我们通过简单设置一些抓取规则,剩下的就交给浏览器去工作。 地址:https://webscraper.io/ 如果你觉得文章不错的话,分享、收藏、在看是对猴哥的最大支持,是毒蜂持续创作的动力。 ...

    2020-04-12 602
  • 我用Python找到了隔壁蹭网妹子的QQ号

    最近发现晚上有人老是在蹭网,而且严重怀疑是我的美女单身邻居,这可是千载难逢的好机会。于是我用Python轻松找到了它的QQ号,开始了我的桃花之旅......下面给大家介绍一下我是怎么做到的。 1、登入路由器进行分析 蹭网的信息全部都在路由器上,所以我们首先要登录路由器,去查探一下线索。果然登入路由器之后,发现有1台陌生的设备华为P30Pro在线,哈哈女神都是用高端手机,我等屌丝还在苦苦坚守16年的华为mate9。 那么如何才能知道女神的QQ号呢,别急别急啊,且听我慢慢给大家分析。 2、抓流量包进行分析 想办法抓取女神的流量包,路由器定向太麻烦,干脆直接把路由器wifi关了,在电脑上插个外置usb网卡,重新开个同名同密码的wifi,到时候女神的手机就可以自动连上了,我只要抓电脑网卡的流量就OK了。 如下图所示,不一会,这台华为P30pro就不知不觉自动连上我新建的wifi了。 3、神库Scapy抓包分析 用Python的scapy库抓包分析,有同学可能不知道这个库,这个库其实非常有用,尤其在网络分析方面,小编简单介绍一下。 1).scapy库简介 scapy是一个可以让用户发送、侦听和解析并伪装网络报文的Python程序。这些功能可以用于制作侦测、扫描网络的工具。 2).用scapy抓usb网卡上的流量: packets=scapy.sniff(iface=iface_name,prn=pktTCP) 一行代码就搞定了,其中iface_name是网卡的名称,在网卡的属性中可以找到,pktTCP是返回的数据包,它长下图这样: 包含数据链路层、网络层、传输层数据。 3).分析数据包,找到有用信息: 这是最重要的一步,过程不难,但比较繁琐,我就不详细说了,直接把结果说出来吧: 经过多次试验,QQ号(一般是5到10位)一般在这2类字符串中后面,通过正则表达式匹配!另外这2类字符串后面跟的也可能是全0数字,要进行简单的筛选。 部分源码如下: 4).运行程序,等待结果,果然没几分钟就搜索到了。 上面那个是我自己的,下面那个是女神的,果断加了过去。 哈哈哈,果然是她。 ...

    2020-01-20 732
  • Python 帮你批量生成手机号码

    阅读文本大概需要 8 分钟。 1 目 标 场 景 平时在工作过程中,偶尔会需要大量的 手机号码,去测试一些具体的业务功能,为了保证测试的有效性,手机号码的 真实性 尤为的重要。 那如何按要求 批量生成 一些真实的手机号码呢? 本篇文章的目的是带大家利用 Python 批量生成手机号码。 2 编 写 代 码 要批量生成手机号码,首先需要了解 11 位手机号码的组成规律,即: 手机号码一共有 11 位,以 1 开头 第 2 位的数值是 3、4、5、7、8 中的一个 第 3 位根据第 2 位的数字,对应运营商的生成规律 后 8 位是随机生成的 8 个数字 知道手机号码的组成规律后,接着把数字拼接起来,即可以生成一个手机号码。 def create_a_phone():     # 第二位数字     second = [3, 4, 5, 7, 8][random.randint(0, 4)]     # 第三位数字     third = {3: random.randint(0, 9),              4: [5, 7, 9][random.randint(0, 2)],              5: [i for i in range(10) if i != 4][random.randint(0, 8)],              7: [i for i in range(10) if i not in [4, 9]][random.randint(0, 7)],              8: random.randint(0, 9), }[second]     # 最后八位数字     suffix = random.randint(9999999, 100000000)     # 拼接手机号     return "1{}{}{}".format(second, third, suffix) 由于三大运营商的号段一直在更新变化,上面组成的手机号码也有可能不是一个有效的号码。 为了保证号码的真实性,利用号码去获取 手机号码归属地,如果能获取到归属地,即代表为一个真实有效的号码。 淘宝和百度都提供了查询归属地的 API,可以非常方便的查询号码的归属地。 def judge_phone_ava(phone):     """     判断手机号码是否合理     :param phone:手机号码     :return:     """     resp_content = requests.get('http://mobsec-dianhua.baidu.com/dianhua_api/open/location?tel=%s' % phone).content     txt = json.loads(resp_content)     result = txt.get('response').get(phone)     return result 循环上面的操作,可以生成一些随机的手机号码,正因为生成号码的随机性,使得数据的价值性大打折扣。 如果我需要批量生成指定城市的手机号码,上面的这种方法没法做到。幸运地是,有一个网站(阅读原文)已经实现了这个功能,我们只需要用 Python 模拟请求即可。 选择手机号码归属地、包含号段、数量,就能快速生成我们想要的手机号码,按 F12 可以查看网络请求方式及参数。 请求参数中的区域代码对应选择的省+市区,这部分数据利用 JS 加载到页面中了。 我们只需要解析网页源代码,利用正则表达式查找对应的字符串,解析出 区域 ID 和城市名称。 def get_all_citys():     """     获取所有的城市数据     :return:     """     headers = {         'authority': 'uutool.cn',         'pragma': 'no-cache',         'cache-control': 'no-cache',         'upgrade-insecure-requests': '1',         'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36',         'sec-fetch-user': '?1',         'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',         'sec-fetch-site': 'none',         'sec-fetch-mode': 'navigate',         'accept-encoding': 'gzip, deflate, br',         'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8',         'cookie': 'UM_distinctid=16f759fe6bd24b-0322efd0d180d8-1d376b5b-1aeaa0-16f759fe6beb69; CNZZDATA1275106188=191793625-1578225029-https%253A%252F%252Fwww.google.com%252F%7C1578316721',     }     resp = requests.get('https://uutool.cn/phone-generate/', headers=headers).text     re_rule = r'areaArr:(.+?)segmentArr:'     # 匹配换行符     result_data = re.findall(re_rule, resp, re.S)[0].strip()[:-1]     result = json.loads(result_data)     # 获取所有的省份     provices = result.keys()     # 所有的城市     citys = {}     for provice in provices:         current_citys = result.get(provice)         # citys.extend(current_citys)         for item in current_citys:             citys[item.get('name')] = item.get('id')     return citys 拿到城市名称和区域 ID 的关系数据后,模拟网络请求,即可以批量生成目标城市的手机号码。 citys = get_all_citys() city_name = input('请输入手机归属地:') if city_name not in citys.keys():      city_name = '北京' # 获取城市id city_id = citys.get(city_name) phones = generate_phones(num, city_id) # pass 3 结 果 结 论 通过上面的操作,就能按照自己的需求,批量生成一些真实有效的手机号码。 接下来,可以结合自动化操作,可以使得我们生成的数据价值最大化。 如果你觉得文章还不错,请大家分享下。你的肯定是我最大的鼓励和支持。 ...

    2020-01-18 826
  • 我背着女朋友,用 Python 偷偷抓取了她的行踪

    阅读文本大概需要 5 分钟。 1 目 标 场 景 有时候女朋友一个人在外面玩耍,问她在哪个地方,就是不告诉我。但是,你又很想知道女朋友的「位置」,这该如何是好? 其实你可以这样套路女朋友,假装自己在家很无聊,可以帮她修图,让她微信发原图给你,拿到「微信原图」后,你就可以利用 Python 快速获取到女友的具体位置了。 2 准 备 工 作 首先,在虚拟环境中安装识别图片元数据的库。 pip3 install exifread 然后,进入高德开放平台,申请一个 Web 服务的应用,获取到一个 「Key」用于逆地理编码 API。 3 编  写  脚  本 整个操作分为 3 步骤,分别是获取图片的经度和纬度、对经度和纬度进行数据矫正、调用高德逆地理编码 API 获取具体位置。 第 1 步,获取图片的「经度和纬度」。 使用 exifread 库可以直接读取图片文件,获取到图片的元数据,包含经度、纬度、南北纬方向、东西经方向和拍摄时间。 # 使用 exifread 获取图片的元数据 img_exif = exifread.process_file(open(self.img_path, 'rb')) # 能够读取到属性 if img_exif:      # 纬度数      latitude_gps = img_exif['GPS GPSLatitude']      # N,S 南北纬方向      latitude_direction = img_exif['GPS GPSLatitudeRef']      # 经度数      longitude_gps = img_exif['GPS GPSLongitude']      # E,W 东西经方向      longitude_direction = img_exif['GPS GPSLongitudeRef']      # 拍摄时间      take_time = img_exif['EXIF DateTimeOriginal'] 如果元数据存在,然后判断拍摄时间是否合理。如果拍摄时间不在今天,那只能很遗憾地通知你,你的女朋友在向你撒谎「撒谎」。 def judge_time_met(self, take_time):     """     判断拍摄时间是否是在今天     :param take_time:     :return:     """     # 拍摄时间     format_time = str(take_time).split(" ")[0].replace(":", "-")     # 当天日期     today = str(datetime.date.today())     if format_time == today:         return True     else:         return False if is_lie:         print('很遗憾的通知你,你的女朋友在撒谎!!!')         return 如果女友没有撒谎,那么可以进行第 2 步的操作。 因为通过 GPS 获取的经度、纬度和高德地图的坐标存在一定的误差,这里需要把坐标转换为「火星坐标系」。 x_pi = 3.14159265358979324 * 3000.0 / 180.0 pi = 3.1415926535897932384626  # π a = 6378245.0  # 长半轴 ee = 0.00669342162296594323  # 扁率 def wgs84togcj02(lng, lat):     """     WGS84转GCJ02(火星坐标系)     :param lng:WGS84坐标系的经度     :param lat:WGS84坐标系的纬度     :return:     """     if out_of_china(lng, lat):  # 判断是否在国内         return lng, lat     dlat = transformlat(lng - 105.0, lat - 35.0)     dlng = transformlng(lng - 105.0, lat - 35.0)     radlat = lat / 180.0 * pi     magic = math.sin(radlat)     magic = 1 - ee * magic * magic     sqrtmagic = math.sqrt(magic)     dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * pi)     dlng = (dlng * 180.0) / (a / sqrtmagic * math.cos(radlat) * pi)     mglat = lat + dlat     mglng = lng + dlng     return [mglng, mglat] 另外需要注意的是,接口中经度、纬度参数只能识别小数点后 6 位,需要对经纬度中的度、分、秒做一定的数据处理,然后再进行四舍五入。 def __format_lati_long_data(self, data):     """     对经度和纬度数据做处理,保留6位小数     :param data: 原始经度和纬度值     :return:     """     # 删除左右括号和空格     data_list_tmp = str(data).replace('[', '').replace(']', '').split(',')     data_list = [data.strip() for data in data_list_tmp]     # 替换秒的值     data_tmp = data_list[-1].split('/')     # 秒的值     data_sec = int(data_tmp[0]) / int(data_tmp[1]) / 3600     # 替换分的值     data_tmp = data_list[-2]     # 分的值     data_minute = int(data_tmp) / 60     # 度的值     data_degree = int(data_list[0])     # 由于高德API只能识别到小数点后的6位     # 需要转换为浮点数,并保留为6位小数     result = "%.6f" % (data_degree + data_minute + data_sec)     return float(result) 第 3 步,调用高德的反地理编码 API,传入申请的应用 Key,就能拿到女朋友的详细地址。 def __get_address(self, location):     """     根据坐标得到详细地址     :param location: 经纬度值     :return:     """     resp = requests.get(self.url_get_position.format(self.api_key, location))     location_data = json.loads(resp.text)     address = location_data.get('regeocode').get('formatted_address')     return address 4 结 果 结 论 确保图片是原图的基础上,可以快速帮你判断女朋友是否在撒谎;如果女朋友没有撒谎,就返回女朋友具体的位置。 如果你觉得文章还不错,请大家分享下。你的肯定是我最大的鼓励和支持。 ...

    2020-01-18 589
  • Python爬虫之-爬取妹子图片

    #coding=utf-8 import requests from bs4 import BeautifulSoup import os all_url = ‘http://www.mzitu.com’ #http请求头 Hostreferer = { ‘User-Agent’:’Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)’, ‘Referer’:’http://www.mzitu.com’ } Picreferer = { ‘User-Agent’:’Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)’, ‘Referer’:’http://i.meizitu.net’ } #此请求头破解盗链 start_html = requests.get(all_url,headers = Hostreferer) #保存地址 path = ‘G:\python\妹子\liang’ #找寻最大页数 soup = BeautifulSoup(start_html.text,”html.parser”) page = soup.find_all(‘a’,class_=’page-numbers’) max_page = page[-2].text same_url = ‘http://www.mzitu.com/page/’ for n in range(1,int(max_page)+1): ul = same_url+str(n) start_html = requests.get(ul, headers = Hostreferer) soup = BeautifulSoup(start_html.text,”html.parser”) all_a = soup.find(‘div’,class_=’postlist’).find_all(‘a’,target=’_blank’) for a in all_a: title = a.get_text() #提取文本 if(title != ”): print(“准备扒取:”+title) #win不能创建带?的目录 if(os.path.exists(path+title.strip().replace(‘?’,”))): #print(‘目录已存在’) flag=1 else: os.makedirs(path+title.strip().replace(‘?’,”)) flag=0 os.chdir(path + title.strip().replace(‘?’,”)) href = a[‘href’] html = requests.get(href,headers = Hostreferer) mess = BeautifulSoup(html.text,”html.parser”) pic_max = mess.find_all(‘span’) pic_max = pic_max[10].text #最大页数 if(flag == 1 and len(os.listdir(path+title.strip().replace(‘?’,”))) >= int(pic_max)): print(‘已经保存完毕,跳过’) continue for num in range(1,int(pic_max)+1): pic = href+’/’+str(num) html = requests.get(pic,headers = Hostreferer) mess = BeautifulSoup(html.text,”html.parser”) pic_url = mess.find(‘img’,alt = title) print(pic_url[‘src’]) #exit(0) html = requests.get(pic_url[‘src’],headers = Picreferer) file_name = pic_url[‘src’].split(r’/’)[-1] f = open(file_name,’wb’) f.write(html.content) f.close() print(‘完成’) print(‘第’,n,’页完成’) ...

    2019-06-30 1290

联系我们

在线咨询:点击这里给我发消息

QQ交流群:KirinBlog

工作日:9:00-23:00,节假日休息

扫码关注