分类目录归档:生活智能化

什么是m3u8格式? Python合并ts文件至mp4格式及解密教程

m3u8是什么格式?m3u8是苹果公司推出的视频播放标准,是m3u的一种,只是编码格式采用的是UTF-8。使用m3u8格式文件主要因为可以实现多码率视频的适配,视频网站可以根据用户的网络带宽情况,自动为客户端匹配一个合适的码率文件进行播放,从而保证视频的流畅度。

m3u8准确来说是一种索引文件,使用m3u8文件实际上是通过它来解析对应的放在服务器上的视频网络地址,从而实现在线播放。它将视频切割成一小段一小段的ts格式的视频文件,然后存在服务器中(现在为了减少I/o访问次数,一般存在服务器的内存中),通过m3u8解析出来路径,然后去请求。

合并 ts 文件其实有很多种方法,有一些教程直接使用 cmd 的 copy 命令直接合并 ts 文件:

copy /b  movie*.ts movie_new.ts

这个方法虽然可以合并,但是无法转化为 mp4 格式,而且也有可能出现视频缺损的情况。因此本文将讲解如何使用 ffmpeg 合并 ts 文件为mp4格式,使用 ffmpeg 也能有效防止视频出现缺损的问题。

1.准备

开始之前,你要确保Python和pip已经成功安装在电脑上,如果没有,请访问这篇文章:超详细Python安装指南 进行安装。

(可选1) 如果你用Python的目的是数据分析,可以直接安装Anaconda:Python数据分析与挖掘好帮手—Anaconda,它内置了Python和pip.

(可选2) 此外,推荐大家用VSCode编辑器来编写小型Python项目:Python 编程的最好搭档—VSCode 详细指南

安装ffmpeg

Mac (打开终端(Terminal), 用 homebrew 安装):

brew install ffmpeg --with-libvorbis --with-sdl2 --with-theora

Linux:

apt-get install ffmpeg libavcodec-extra

Windows:

1. 进入 http://ffmpeg.org/download.html#build-windows,点击 windows 对应的图标,进入下载界面点击 download 下载按钮,
2. 解压下载好的zip文件到指定目录
3. 将解压后的文件目录中 bin 目录(包含 ffmpeg.exe )添加进 path 环境变量中
4. DOS 命令行输入 ffmpeg -version, 出现以下界面说明安装完成:

2.简单合并ts文件

使用 ffmpeg 合并一些 ts 文件非常简单,你只需要在终端输入一行命令即可:

ffmpeg -f concat -i file_list.txt -c copy output.mp4

其中 file_list.txt 为如下格式文本文件:

      file 'input1.ts'
      file 'input2.ts'
      file 'input3.ts'

我们可以用 Python 脚本生成这个 file_list.txt:

import os
filePath = "你的ts视频存放路径"
file_list = sorted(os.listdir(filePath))
with open("你的ts视频存放路径/file_list.txt","w+") as f:
    for file in file_list:
        f.write("file '{}'\n".format(file))

注意,这个 file_list.txt 需要和你的 ts 视频存放在同一个目录下,然后 cd 进入此目录,并执行上面提到过的 ffmpeg 合并转换命令:

ffmpeg -f concat -i file_list.txt -c copy output.mp4

3.解密处理

上面我们讲的是没有经过加密的 ts 文件,这些文件下载后直接可以播放,但经过AES-128加密后的文件下载后会无法播放,所以还需要进行解密。

如何判断是否需要加密?观察视频网站是否有m3u8的文件传输,下载下来并打开:

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:13
#EXT-X-MEDIA-SEQUENCE:0

//这里是注释,真实文件里不会有的,
//看看你的m3u8文件里有没有这一行,如果有的话,这个m3u8文件是加密的,请继续往下看
//如果没有这行的话,特别是没有这个#EXT-X-KEY,那么恭喜你,这个m3u8没有加密,你直接按本文教程第二点合并即可
#EXT-X-KEY:METHOD=AES-128,URI="http://www.example.com/20180125/key.key"


#EXTINF:12.5,
//下面的这个其实才是视频真正的地址,你放在浏览器地址栏上直接回车是可以直接下载的
//不过这样的链接在m3u8文件里会有很多,建议使用工具下载(迅雷)、ffmpeg、vlc等
//这里还可能出现GBDYO3576000.ts这种情况,其实是把前面的路径省略了,可根据m3u8文件的路径自行加上
http://www.example.com/20180125/GBDYO3576000.ts
#EXTINF:12.5,
http://www.example.com/20180125/GBDYO3576001.ts
#EXTINF:12.5,
http://www.example.com/20180125/GBDYO3576002.ts

如果你的文件是加密的,那么你还需要一个key文件,Key文件下载的方法和m3u8文件类似,如下所示 key.key 就是我们需要下载的 key 文件,并注意这里 m3u8 有2个,需要使用的是像上面一样存在 ts 文件超链接的 m3u8 文件:

下载所有 ts 文件,将下载好的所有的 ts 文件、m3u8、key.key 放到一个文件夹中,将 m3u8 文件改名为 index.m3u8,将 key.key 改名为 key.m3u8 。更改 index.m3u8 里的 URL,变为你本地路径的 key 文件,将所有 ts 也改为你本地的路径,如下所示:

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:13
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-KEY:METHOD=AES-128,URI="e:/20180125/key.m3u8"
#EXTINF:12.5,
e:/20180125/GBDYO3576000.ts
#EXTINF:12.5,
e:/20180125/GBDYO3576001.ts
#EXTINF:12.5,
e:/20180125/GBDYO3576002.ts

然后用ffmpeg进行合并:

ffmpeg -allowed_extensions ALL -i index.m3u8 -c copy new.mp4

这样就大功告成了!我们成功解密并使用 ffmpeg 合并了这些 ts 视频片段,实际应用场景可能和这不一样,希望我们这篇文章能起到抛砖引玉的作用。

我们的文章到此就结束啦,如果你喜欢今天的 Python 教程,请持续关注Python实用宝典。

有任何问题,可以在公众号后台回复:加群,回答相应验证信息,进入互助群询问。

原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!

给作者打赏,选择打赏金额
¥1¥5¥10¥20¥50¥100¥200 自定义

​Python实用宝典 ( pythondict.com )
不只是一个宝典
欢迎关注公众号:Python实用宝典

强大的Json解析工具 Jsonpath Python 实战教程

 

JsonPath是一种简单的方法来提取给定JSON文档的部分内容。 JsonPath有许多编程语言,如Javascript,Python和PHP,Java。JsonPath提供的json解析非常强大,它提供了类似正则表达式的语法,基本上可以满足所有你想要获得的json内容。

本文介绍了Json相关的基础知识,引入XML和Jsonpath的对比,说明Jsonpath出现的必要性,并在文末附上了 Jsonpath 实战教程。

1.关于JSON

JSON是一个标记符序列。这套标记符包括:构造字符、字符串、数字和三个字面值

构造字符

JSON包括六个构造字符,分别是:左方括号、右方括号、左大括号、右大括号、冒号与逗号。

JSON值

JSON值可以是对象、数组、数字、字符串或者三个字面值(false、true、null),并且字面值必须是小写英文字母。

对象

对象是由花括号括起来,逗号分割的成员构成,成员是字符串键和上面所说的JSON值构成,例如:

{"name":"jack","age":18,"address":{"country"}}

数组

数组是由方括号括起来的一组数值构成,例如:

[1,2,32,3,6,5,5]

字符串与数字想必就不用我过多叙述吧。

下面我就举例一些合法的JSON格式的数据:

{"a":1,"b":[1.2.3]}
[1,2,"3",{"a":4}]
3.14
"json_data"

2.为什么要使用JSON

JSON是一种轻量级的数据交互格式,它使得人们很容易的进行阅读和编写。同时也方便机器进行解析和生成。适用于进行数据交互的场景,比如网站前台与后台之间的数据交互。

JSON的使用方法

json.loads()

把JSON格式字符串解码转成Python对象,从JSON到Python类型转换表如下:

JSON Python
object dict
array list
string str
number(int) int
number(real) float
true True
false False
null None
  • 将数组转成列表对象
import json


strList = "[1,2,3,3,4]"
print(json.loads(strList))
print(type(json.loads(strList)))

试着运行上面的代码,你会发现已经成功的将strList转换为列表对象。

  • 将对象转换成字典
import json


strDict = '{"city":"上海","name":"jack","age":18}'
print(json.loads(strDict))
print(type(json.loads(strDict)))

试着运行上面的代码,你会发现已经成功的将object转换为dict类型的数据。

json.dumps()

其实这个方法也很好理解,就是将Python类型的对象转换为json字符串。从Python类型向JSON类型转换的对照表如下:

 

python JSON
dict object
list, tuple array
str string
int, float number
True true
False false
None null
  • 将Python列表对象转换为JSON字符串
import json


list_str = [1,2,3,6,5]
print(json.dumps(list_str))
print(type(json.dumps(list_str)))

试着运行上面的代码,你会发现成功的将列表类型转换成了字符串类型。

  • 将Python元组对象转换为JSON字符串
import json


tuple_str = (1,2,3,6,5)
print(json.dumps(tuple_str))
print(type(json.dumps(tuple_str)))

试着运行上面的代码,你会发现成功的将元组类型的数据转换成了字符串。

  • 将Python字典对象转换为JSON字符串
import json 


dict_str = {"name""小明""age":18"city""中国深圳"}
print(json.dumps(dict_str))
print(type(json.dumps(dict_str)))

输出结果:

{"name""\u5c0f\u660e""age": 18, "city""\u4e2d\u56fd\u6df1\u5733"}
<class 'str'>

看到上面的输出结果也许你会有点疑惑,其实不需要疑惑,这是ASCII编码方式造成的,因为**json.dumps()**做序列化操作时默认使用的就是ASCII编码,因此我们可以这样写:

import json


dict_str = {"name""小明""age":18"city""中国深圳"}
print(json.dumps(dict_str, ensure_ascii=False))
print(type(json.dumps(dict_str)))

输出结果:

{"name""小明""age": 18, "city""中国深圳"}
<class 'str'>

因为ensure_ascii的默认值是True,因此我们可以添加参数ensure_ascii将它的默认值改成False,这样编码方式就会更改为utf-8了。

json.load()

该方法的主要作用是将文件中JSON形式的字符串转换为Python类型。

具体代码示例如下:

import json

str_list = json.load(open('position.json', encoding='utf-8'))
print(str_dict)
print(type(str_dict))

运行上面的代码,你会发现成功的将字符串类型的JSON数据转换为了dict类型。

代码中的文件position.json我也会分享给大家。

  • json.dump()

将Python内置类型序列化为JSON对象后写入文件。具体代码示例如下所示:

import json

list_str = [{'city':'深圳'}, {'name''小明'},{'age':18}]
dict_str = {'city':'深圳','name':'小明','age':18}

json.dump(list_str, open('listStr.json''w'), ensure_ascii=False)
json.dump(list_str, open('dictStr.json''w'), ensure_ascii=False)

3.jsonpath

XML的优点是提供了大量的工具来分析、转换和有选择地从XML文档中提取数据。Xpath是这些功能强大的工具之一。

对于JSON数据来说,也出现了jsonpath这样的工具来解决这些问题:

  • 数据可以通过交互方式从客户端上的JSON结构提取,不需要特殊的脚本。
  • 客户端请求的JSON数据可以减少到服务器的上的相关部分,从而大幅度减少服务器响应的带宽使用。

jsonpath表达式始终引用JSON结构的方式与Xpath表达式与XML文档使用的方式相同。

jsonpath的安装方法

pip install jsonpath

jsonpath与Xpath

下面表格是jsonpath语法与Xpath的完整概述和比较。

Xpath jsonpath 概述
/ $ 根节点
. @ 当前节点
/ .or[] 取子节点
* * 匹配所有节点
[] [] 迭代器标识(如数组下标,根据内容选值)
// 不管在任何位置,选取符合条件的节点
n/a [,] 支持迭代器中多选
n/a ?() 支持过滤操作
n/a () 支持表达式计算

下面我们就通过几个示例来学习jsonxpath的使用方法。

我们先来看下面这段json数据

"store": {
    "book": [
      { "category""reference",
        "author""Nigel Rees",
        "title""Sayings of the Century",
        "price"8.95
      },
      { "category""fiction",
        "author""Evelyn Waugh",
        "title""Sword of Honour",
        "price"12.99
      },
      { "category""fiction",
        "author""Herman Melville",
        "title""Moby Dick",
        "isbn""0-553-21311-3",
        "price"8.99
      },
      { "category""fiction",
        "author""J. R. R. Tolkien",
        "title""The Lord of the Rings",
        "isbn""0-395-19395-8",
        "price"22.99
      }
    ],
    "bicycle": {
      "color""red",
      "price"19.95
    }
  }
}

获取符合条件的节点

假如我需要获取到作者的名称该怎么样写呢?

如果通过Python的字典方法来获取是非常麻烦的,所以在这里我们可以选择使用jsonpath.。

具体代码示例如下所示:

import jsonpath


author = jsonpath.jsonpath(data_json, '$.store.book[*].author')
print(author)

运行上面的代码你会发现,成功的获取到了所有的作者名称,并保存在列表中。

或者还可以这样写:

import jsonpath

author = jsonpath.jsonpath(data_json, '$..author')
print(author)

使用指定索引

还是使用上面的json数据,假如我现在需要获取第三本书的价格。

third_book_price = jsonpath.jsonpath(data_json, '$.store.book[2].price')
print(third_book_price)

运行上面的代码,你会发现成功的获取到了第三本书的价格。

使用过滤器

isbn_book = jsonpath.jsonpath(data_json, '$..book[?(@.isbn)]')
print(isbn_book)
print(type(isbn_book))

通过运行上面的代码,你会发现,成功的将含有isbn编号的书籍过滤出来了。

同样的道理,根据上面的例子,我们也可以将价格小于10元的书过滤出来。

book = jsonpath.jsonpath(data_json, '$..book[?(@.price<10)]')
print(book)
print(type(book))

通过运行上面的代码,你会发现这里已经成功的将价格小于10元的书提取出来了。

jsonpath其实是非常适合用来获取json格式的数据的一款工具,最重要的是这款工具轻量简单容使用。关于jsonpath的介绍到这里就结束了,下面我们就进入实战演练吧!

4.Jsonpath 实战教程

前言

每年的6月份都是高校学生的毕业季,作为计算机专业的你来说,如果刚刚毕业就可以进入大厂,想必是一个非常不错的选择。因此,今天我带来的项目就是爬取腾讯招聘的网站,获取职位名称、职位类别、工作地点、工作国家、职位的更新时间、职位描述

爬取内容一共有329页,在前329页的职位都是在这个月发布的,还是比较新,对大家来说更有参考的价值。

网页链接:https://careers.tencent.com/search.html

准备

工欲善其事,必现利其器。首先我们要准备好几个库:pandas、requests、jsonpath

如果没有安装,请参考下面的安装过程:

pip install requests
pip install pandas
pip install jsonpath

需求分析与功能实现

获取所有的职位信息

对网页进行分析的时候,我发现想从网页上直接获取信息是是做不到的,该网页的响应信息如下所示:

<!DOCTYPE html><html><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="initial-scale=1,maximum-scale=1,user-scalable=no"><meta name=keywords content=""><meta name=description content=""><meta name=apple-mobile-web-app-capable content=no><meta name=format-detection content="telephone=no"><title>搜索 | 腾讯招聘</title><link rel=stylesheet href=https://cdn.multilingualres.hr.tencent.com/tencentcareer/static/css/main.css><link rel=stylesheet href=https://cdn.multilingualres.hr.tencent.com/tencentcareer/static/css/jquery-ui.min.css></head><body><div id=app></div><script type=text/javascript src=https://cdn.multilingualres.hr.tencent.com/careersmlr/HeadFoot_zh-cn.js></script><script type=text/javascript src=https://cdn.multilingualres.hr.tencent.com/careersmlr/HostMsg_zh-cn.js></script><script type=text/javascript src=https://cdn.multilingualres.hr.tencent.com/careersmlr/Search_zh-cn.js></script><script type=text/javascript src=https://cdn.multilingualres.hr.tencent.com/tencentcareer/static/js/vendor/config.js></script><script type=text/javascript src=https://cdn.multilingualres.hr.tencent.com/tencentcareer/static/js/vendor/jquery.min.js></script><script type=text/javascript src=https://cdn.multilingualres.hr.tencent.com/tencentcareer/static/js/vendor/jquery.ellipsis.js></script><script type=text/javascript src=https://cdn.multilingualres.hr.tencent.com/tencentcareer/static/js/vendor/report.js></script><script type=text/javascript src=https://cdn.multilingualres.hr.tencent.com/tencentcareer/static/js/vendor/qrcode.min.js></script><script type=text/javascript src=https://cdn.multilingualres.hr.tencent.com/tencentcareer/static/js/manifest.build.js></script><script type=text/javascript src=https://cdn.multilingualres.hr.tencent.com/tencentcareer/static/js/vendor.build.js></script><script type=text/javascript src=https://cdn.multilingualres.hr.tencent.com/tencentcareer/static/js/p_zh-cn_search.build.js></script></body><script type=text/javascript src=https://cdn.multilingualres.hr.tencent.com/tencentcareer/static/js/vendor/common.js></script></html>

因此我判断,这个是动态Ajax加载的数据,因此就要去网页控制器上查找职位数据是否存在。

经过一番查找,果然发现是动态加载的数据,信息如下所示:

格式化之后的数据如下所示:

{
    "Code":200,
    "Data":{
        "Count":8500,
        "Posts":[
            {
                "Id":0,
                "PostId":"1346716678288842752",
                "RecruitPostId":71330,
                "RecruitPostName":"41071-腾讯会议项目经理(西安)(CSIG全资子公司)",
                "CountryName":"中国",
                "LocationName":"西安",
                "BGName":"CSIG",
                "ProductName":"腾讯云",
                "CategoryName":"产品",
                "Responsibility":"1、负责研发项目及研发效能的计划制定、进度驱动和跟踪、风险识别以及应对,确保项目按计划完成;
2、负责组织项目各项评审会议及项目例会,制定并推广项目流程规范,确保项目有序进行;
3、负责与项目外部合作伙伴进行沟通,制定流程规范双方合作,并推动合作事宜;
4、及时发现并跟踪解决项目问题,有效管理项目风险。
"
,
                "LastUpdateTime":"2021年01月21日",
                "PostURL":"http://careers.tencent.com/jobdesc.html?postId=1346716678288842752",
                "SourceID":1,
                "IsCollect":false,
                "IsValid":true
            },
            {
                "Id":0,
                "PostId":"1346716729744564224",
                "RecruitPostId":71331,
                "RecruitPostName":"41071-腾讯会议产品策划(平台方向)(CSIG全资子公司)",
                "CountryName":"中国",
                "LocationName":"西安",
                "BGName":"CSIG",
                "ProductName":"腾讯云",
                "CategoryName":"产品",
                "Responsibility":"1、负责腾讯会议企业管理平台的产品策划工作,包括企业运营平台、运维、会控平台和工具的产品设计和迭代优化;
2、协调和推动研发团队完成产品开发、需求落地,并能在需求上线后进行持续数据分析和反馈跟进,不断提升产品竞争力;
3、根据行业场景抽象用户需求,沉淀面向不同类型客户的云端管控平台解决方案;
 "
,
                "LastUpdateTime":"2021年01月21日",
                "PostURL":"http://careers.tencent.com/jobdesc.html?postId=1346716729744564224",
                "SourceID":1,
                "IsCollect":false,
                "IsValid":true
            },
            {
                "Id":0,
                "PostId":"1346062593894129664",
                "RecruitPostId":71199,
                "RecruitPostName":"41071-腾讯会议产品策划(CSIG全资子公司)",
                "CountryName":"中国",
                "LocationName":"西安",
                "BGName":"CSIG",
                "ProductName":"腾讯云",
                "CategoryName":"产品",
                "Responsibility":"负责腾讯会议的产品策划工作:
1、研究海外用户办公习惯及SaaS市场动态,调研海外相关SaaS产品并输出产品调研结论,综合市场情况和用户需求输出高质量的产品需求或解决方案;
2、负责腾讯会议各产品线的英文版的功能同步和产品设计工作,把关产品功能同步和国际版需求改造等;
3、协调和推动研发团队完成产品开发、需求落地,并能在需求上线后进行持续数据分析和反馈跟进,不断提升产品竞争力; "
,
                "LastUpdateTime":"2021年01月21日",
                "PostURL":"http://careers.tencent.com/jobdesc.html?postId=1346062593894129664",
                "SourceID":1,
                "IsCollect":false,
                "IsValid":true
            },
            {
                "Id":0,
                "PostId":"1352161575309418496",
                "RecruitPostId":72134,
                "RecruitPostName":"CSIG16-推荐算法高级工程师",
                "CountryName":"中国",
                "LocationName":"北京",
                "BGName":"CSIG",
                "ProductName":"",
                "CategoryName":"技术",
                "Responsibility":"1. 参与地图场景下推荐算法优化,持续提升转化效果和用户体验;
2. 负责地图场景下推荐引擎架构设计和开发工作;
3. 跟进业界推荐领域最新进展,并推动其在地图场景下落地。"
,
                "LastUpdateTime":"2021年01月21日",
                "PostURL":"http://careers.tencent.com/jobdesc.html?postId=0",
                "SourceID":1,
                "IsCollect":false,
                "IsValid":true
            },
            {
                "Id":0,
                "PostId":"1352158432852975616",
                "RecruitPostId":72133,
                "RecruitPostName":"41071-腾讯云SDK 终端研发工程师(CSIG全资子公司)",
                "CountryName":"中国",
                "LocationName":"西安",
                "BGName":"CSIG",
                "ProductName":"",
                "CategoryName":"技术",
                "Responsibility":"1. 负责腾讯云 GME SDK(游戏多媒体引擎)的开发和优化工作,并配套开发相应的场景解决方案业务流程,以满足不同场景和不同行业的客户需求; 
2. 全流程参与客户需求咨询、需求评估、方案设计、方案编码实施及交付工作; 
3. 负责优化腾讯云GME产品易用性,并跟踪客户的接入成本、完善服务体系,解决客户使用产品服务和解决方案过程中的技术问题,不断完善问题处理机制和流程。"
,
                "LastUpdateTime":"2021年01月21日",
                "PostURL":"http://careers.tencent.com/jobdesc.html?postId=0",
                "SourceID":1,
                "IsCollect":false,
                "IsValid":true
            },
            {
                "Id":0,
                "PostId":"1352155053116366848",
                "RecruitPostId":72131,
                "RecruitPostName":"40931-智慧交通数据平台前端开发工程师(北京)",
                "CountryName":"中国",
                "LocationName":"北京",
                "BGName":"CSIG",
                "ProductName":"",
                "CategoryName":"技术",
                "Responsibility":"负责腾讯智慧交通领域的平台前端开发工作;
负责规划与制定前端整体发展计划与基础建设;
负责完成前端基础架构设计与组件抽象。"
,
                "LastUpdateTime":"2021年01月21日",
                "PostURL":"http://careers.tencent.com/jobdesc.html?postId=0",
                "SourceID":1,
                "IsCollect":false,
                "IsValid":true
            },
            {
                "Id":0,
                "PostId":"1306860769169645568",
                "RecruitPostId":66367,
                "RecruitPostName":"35566-HRBP(腾讯全资子公司)",
                "CountryName":"中国",
                "LocationName":"武汉",
                "BGName":"CSIG",
                "ProductName":"",
                "CategoryName":"人力资源",
                "Responsibility":"负责区域研发公司的HR政策、制度、体系与重点项目在部门内部的落地与推动执行;
深入了解所负责领域业务与人员发展状况,评估并明确组织与人才发展对HR的需求;
驱动平台资源提供HR解决方案,并整合内部资源推动执行;提升管理干部的人力资源管理能力,关注关键人才融入与培养,确保持续的沟通与反馈;
协助管理层进行人才管理、团队发展、组织氛围建设等,确保公司文化在所属业务领域的落地;
负责所对接部门的人才招聘工作;
"
,
                "LastUpdateTime":"2021年01月21日",
                "PostURL":"http://careers.tencent.com/jobdesc.html?postId=1306860769169645568",
                "SourceID":1,
                "IsCollect":false,
                "IsValid":true
            },
            {
                "Id":0,
                "PostId":"1351353005709991936",
                "RecruitPostId":71981,
                "RecruitPostName":"35566-招聘经理(腾讯云全资子公司)",
                "CountryName":"中国",
                "LocationName":"武汉",
                "BGName":"CSIG",
                "ProductName":"",
                "CategoryName":"人力资源",
                "Responsibility":"1、负责CSIG区域研发公司相关部门的社会招聘及校园招聘工作,制定有效的招聘策略并推动落地执行,保障人才开源、甄选和吸引;
2、负责相关部门人力资源市场分析,有效管理并优化招聘渠道;
3、参与招聘体系化建设,甄选相关优化项目,有效管理及优化招聘渠道。"
,
                "LastUpdateTime":"2021年01月21日",
                "PostURL":"http://careers.tencent.com/jobdesc.html?postId=1351353005709991936",
                "SourceID":1,
                "IsCollect":false,
                "IsValid":true
            },
            {
                "Id":0,
                "PostId":"1351838518279675904",
                "RecruitPostId":72081,
                "RecruitPostName":"35566-雇主品牌经理(腾讯云全资子公司)",
                "CountryName":"中国",
                "LocationName":"武汉",
                "BGName":"CSIG",
                "ProductName":"",
                "CategoryName":"人力资源",
                "Responsibility":"1、负责腾讯云区域研发公司雇主品牌的规划和建设工作,结合业务招聘需求,制定有效的品牌方案;
2、负责讯云区域研发公司的公众号、媒体账号的内容策划、撰写,协调相关资源完成高质量内容输出;
3、负责招聘创意项目的策划和项目统筹,借助各种平台渠道,完成创意内容的传播触达,提升人选对腾讯云区域研发公司的认知和意向度;"
,
                "LastUpdateTime":"2021年01月21日",
                "PostURL":"http://careers.tencent.com/jobdesc.html?postId=1351838518279675904",
                "SourceID":1,
                "IsCollect":false,
                "IsValid":true
            },
            {
                "Id":0,
                "PostId":"1199244591342030848",
                "RecruitPostId":55432,
                "RecruitPostName":"22989-数据库解决方案架构师(北京/上海/深圳)",
                "CountryName":"中国",
                "LocationName":"上海",
                "BGName":"CSIG",
                "ProductName":"",
                "CategoryName":"产品",
                "Responsibility":"支持客户的应用架构设计,了解客户的业务逻辑和应用架构,给出合理的产品方案建议; 
支持客户的数据库方案设计,从运维、成本、流程等角度主导云数据库产品落地; 
梳理客户的核心诉求,提炼为普适性的产品能力,推动研发团队提升产品体验;
根据客户的行业属性,定制行业场景的解决方案,提升云数据库的影响力;"
,
                "LastUpdateTime":"2021年01月21日",
                "PostURL":"http://careers.tencent.com/jobdesc.html?postId=1199244591342030848",
                "SourceID":1,
                "IsCollect":false,
                "IsValid":true
            }
        ]
    }
}

经过对比发现上面的json数据与网页信息是完全相同的。

看到json数据你有没有一丝的惊喜,终于到了可以大显身手的时候了。

你会发现,上面每一个节点的参数都是独立的,不会存在重复,那我们可以这样写:

def get_info(data):
    recruit_post_name = jsonpath.jsonpath(data, '$..RecruitPostName')
    category_name = jsonpath.jsonpath(data, '$..CategoryName')
    country_name= jsonpath.jsonpath(data, '$..CountryName')
    location_name = jsonpath.jsonpath(data, '$.Data.Posts..LocationName')
    responsibility = jsonpath.jsonpath(data, '$..Responsibility')
    responsibility = [i.replace('\n''').replace('\r'''for i in responsibility]
    last_update_time = jsonpath.jsonpath(data, '$..LastUpdateTime')

运行上面的代码,你会发现成功的获取到了每一组数据。

关于翻页

打开网页之后你会发现腾讯的职位信息一共有850页,但是前面的json数据仅仅只有第一页的数据怎么办呢?

不用担心,直接点击第二页看看网络数据有什么变化。

如上图所示,当点击第二页的时候,又加载出来了一个数据,点击进去之后你就会发现,这个数据刚好就是第二页的职位信息。

那接下来就是发现规律的时候了,第一页与第二页保存JSON数据的URL如下所示:

# 第一页
https://careers.tencent.com/tencentcareer/api/post/Query?timestamp=1611215870971&countryId=&cityId=&bgIds=&productId=&categoryId=&parentCategoryId=&attrId=&keyword=&pageIndex=1&pageSize=10&language=zh-cn&area=cn

# 第二页
https://careers.tencent.com/tencentcareer/api/post/Query?timestamp=1611217026103&countryId=&cityId=&bgIds=&productId=&categoryId=&parentCategoryId=&attrId=&keyword=&pageIndex=2&pageSize=10&language=zh-cn&area=cn

经过测试发现,可以将URL地址进行简化,简化后的URL如下所示:

# 第一页
https://careers.tencent.com/tencentcareer/api/post/Query?pageIndex=1&pageSize=10

# 第二页
https://careers.tencent.com/tencentcareer/api/post/Query?pageIndex=1&pageSize=10

数据保存

将爬取下来的数据保存至csv文件,核心代码如下所示:

df = pd.DataFrame({
        'country_name': country_name,
        'location_name': location_name,
        'recruit_post_name':recruit_post_name,
        'category_name': category_name,
        'responsibility':responsibility,
        'last_update_time':last_update_time
    })

if __name__ == '__main__':
    tengxun = TengXun()
    df = pd.DataFrame(columns=['country_name''location_name''category_name','recruit_post_name''responsibility''last_update_time'])

    for page in range(1330):
        print(f'正在获取第{page}页')
        url = tengxun.get_url(page)
        data = tengxun.get_json(url)
        time.sleep(0.03)

        df1 = get_info(data)
        df = pd.concat([df, df1])
        df = df.reset_index(drop=True)
    # pprint.pprint(data)

    df.to_csv('../data/腾讯招聘.csv', encoding='utf-8-sig')

最后结果

 

我们的文章到此就结束啦,如果你喜欢今天的Python 实战教程,请持续关注Python实用宝典。

有任何问题,可以在公众号后台回复:加群,回答相应红字验证信息,进入互助群询问。

原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!

点击下方阅读原文可获得更好的阅读体验

Python实用宝典 (pythondict.com)
不只是一个宝典
欢迎关注公众号:Python实用宝典

什么是腾讯蓝鲸运维体系?附部署教程

腾讯蓝鲸智云是一个高效的运维基础服务自动化体系,拥有支撑数百款腾讯业务的经验沉淀,是一个相对成熟稳定的运维系统。

简而言之,基于蓝鲸这套体系,你可以很方便地管控多个主机、执行作业、监控其运行状态。

此外,基于蓝鲸体系的PaaS平台,你可以非常方便地自动化部署那些使用Golang或Python开发面向内网的SaaS应用。

当然,蓝鲸这套体系不仅仅可以用于运维,比如蓝鲸监控赋予了用户比较大的灵活性,你可以配置脚本采集上报任意你需要监测的数据到蓝鲸监控并配置告警。

社区版是腾讯蓝鲸为运维社区用户免费开放的一套可独立搭建部署的版本,下面给大家提供单机部署的完整指引。

1.软件包准备

进入蓝鲸官网获取「蓝鲸社区版」安装包和部署脚本,并上传到服务器的data目录下,我这里在 xshell 使用 rz -E 上传文件包:

2.解压软件包

使用 tar -xvf 命令解压社区版软件包:

tar -xvf /data/bkce_src-xx.tar.gz -C /data/

xx 是你所下载的社区版版本号。

软件包比较大,解压需要一定时间。

3.安装证书:

运行以下命令,获取MAC地址,拷贝下来到官网输入证书并下载:

cat /sys/class/net/eth0/address
# 52:54:00:xx:xx:xx

将下载完成的证书传到/data/目录下,并解压证书文件到 /data/src/cert 目录:

cd /data/install
install -d -m 755 /data/src/cert
tar -xvf /data/ssl_certificates.tar.gz -C /data/src/cert/

4.修改蓝鲸配置参数

解压各个产品软件包并拷贝 rpm 软件包:

cd /data/src/; for f in *gz;do tar xf $f; done
cp -a /data/src/yum /opt

修改 bk_install 脚本,如图在 job 处添加以下内容:

vim /data/install/bk_install
sed -i '/JAVA_OPTS/c JAVA_OPTS="-Xms128m -Xmx128m"' /etc/sysconfig/bk-job-*

去除 install_minibk 的 .path 配置:

sed  -i '33,34d' /data/install/install_minibk

在 install.config.3ip.sample 文件追加一行空行:

echo >> /data/install/install.config.3ip.sample

install.config 这个文件安装脚本会自动生成,无需自行配置。

5.开始安装

启动安装脚本,运行命令:

cd /data/install 
./install_minibk -y

安装过程中遇到失败的情况,请先定位排查解决后,再重新运行失败时的安装指令。

执行完部署后,执行降低内存消耗脚本。以确保环境的稳定:

cd /data/install

sed -i '/^cheaper/d' /data/bkce/etc/uwsgi-*.ini 

# 执行降低内存消耗脚本
bash bin/single_host_low_memory_config.sh tweak all

6.安装完成,访问蓝鲸

初始化蓝鲸业务拓扑:

./bkcli initdata topo

由于没有实际域名分配,所以需要配置你本地 PC 的 hosts 文件来访问;打开你电脑里的 hosts文件(windows: C:\windows\system32\drivers\etc\hosts, linux/mac: /etc/hosts)

将下面域名配置复制粘贴至底部,并保存!

10.0.0.1 paas.bktencent.com cmdb.bktencent.com job.bktencent.com jobapi.bktencent.com nodeman.bktencent.com

其中 10.0.0.1 记得替换为你的服务器地址,然后在机器上运行下列命令获取ADMIN账号的用户名和密码:

grep -E "BK_PAAS_ADMIN_USERNAME|BK_PAAS_ADMIN_PASSWORD" /data/install/bin/04-final/usermgr.env

打开下面网址并输入用户名和密码,就能成功访问蓝鲸了。

如果你想了解蓝鲸中配置平台、作业平台、监控平台等产品的使用方法,可以访问蓝鲸官方文档查询:

https://bk.tencent.com/docs/document/6.0/128/5859

下一篇文章,我们将给大家探讨蓝鲸监控的几种有趣的使用方法,基于蓝鲸监控的采集配置功能,我们能实现一些非常有趣的告警策略,敬请期待。

我们的文章到此就结束啦,如果你喜欢今天的 Python 教程,请持续关注Python实用宝典。

有任何问题,可以在公众号后台回复:加群,回答相应验证信息,进入互助群询问。

原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!

给作者打赏,选择打赏金额
¥1¥5¥10¥20¥50¥100¥200 自定义

​Python实用宝典 ( pythondict.com )
不只是一个宝典
欢迎关注公众号:Python实用宝典

3分钟部署Python Web应用,云开发快来了解一下

1. 编写云开发基础应用

创建名为 helloworld 的新目录,并转到此目录中:

mkdir hello-cloud-develop
cd hello-cloud-develop

创建名为 main.py 的文件,并将以下代码粘贴到其中:

import os
from flask import Flask

app = Flask(__name__)


@app.route('/')
def hello_world():
    return 'Hello World!'
  
if __name__ == "__main__":
    app.run(debug=True, host='0.0.0.0', port=8080)

以上代码会创建一个基本的 Web 服务器,并监听 8080 端口。

2. 将应用容器化

在项目根目录下,创建一个名为 Dockerfile 的文件,内容如下:

# 使用官方 Python 轻量级镜像
# https://hub.docker.com/_/python
FROM python:3.8-slim
# 将本地代码拷贝到容器内
ENV APP_HOME /app
WORKDIR $APP_HOME
COPY . ./
# 安装依赖
RUN pip install Flask gunicorn
# 启动 Web 服务
# 这里我们使用了 gunicorn 作为 Server,1 个 worker 和 8 个线程
# 如果您的容器实例拥有多个 CPU 核心,我们推荐您把线程数设置为与 CPU 核心数一致
CMD exec gunicorn --bind :8080 --workers 1 --threads 8 --timeout 0 main:app

添加一个 .dockerignore 文件,以从容器映像中排除文件:

Dockerfile
README.md
*.pyc
*.pyo
*.pyd
__pycache__
.pytest_cache

3.部署到 CloudBase 云托管

你可以选择任何云服务商的云开发服务,这里我选择了腾讯云的CloudBase云托管服务。

在 云托管控制台 的服务列表页面,选择对应的环境,单击【新建服务】。

填写新建服务所需的所有信息默认使用系统推荐的配置即可。

单击【提交】,如果部署成功,便可以看到如下弹框:

单击【新建版本】可立刻开始新建版本并部署,在这里我们选择本地代码,将刚刚写好的文件夹打包为zip文件并上传,端口改为【8080】,流量策略改为【部署完成后自动开启100%流量】,其他配置默认即可:

PS: hello-cloud-develop.zip 可在 Python实用宝典 公众号后台回复:云开发 下载

当然,你也可以选择其他的拉取代码方式,比如代码库或者Docker镜像,按需选择即可。点击开始部署将代码仓库部署为线上服务。

状态变成正常说明部署成功。

4.访问网站

部署成功后就可以访问网站了,进入服务配置,找到公网域名:

这个公网域名就是我们部署网站的地址,访问这个公网域名,出现下面页面效果,说明部署成功:

恭喜!你已经成功通过云开发部署一个网站了,准确来讲是云托管服务。这种部署方式实在非常舒服,无需自建服务器、成本降低、运维省事。

那些简单的个人网站、官方网站或者论坛,我认为都可以用云托管的形式去部署,能够大大节省投入成本,站长们可以尝试一下。

本文全部代码和文件可在 Python实用宝典 公众号后台回复:云开发 下载。

我们的文章到此就结束啦,如果你喜欢今天的 Python 教程,请持续关注Python实用宝典。

有任何问题,可以在公众号后台回复:加群,回答相应验证信息,进入互助群询问。

原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!

给作者打赏,选择打赏金额
¥1¥5¥10¥20¥50¥100¥200 自定义

​Python实用宝典 ( pythondict.com )
不只是一个宝典
欢迎关注公众号:Python实用宝典

Schedule—简单实用的Python 周期任务调度工具

如果你想周期性地执行某个Python函数或脚本,最出名的选择应该是Crontab,但是Crontab具有以下缺点:

  • 1.不方便执行秒级任务。
  • 2.当需要执行的定时任务有上百个的时候,Crontab的管理就会特别不方便。

还有一个选择是Celery,但是Celery的配置比较麻烦,如果你只是需要一个轻量级的调度工具,那么Celery不是一个好选择。

在你想要使用一个轻量级的任务调度工具,而且希望它尽量简单、容易使用、不需要外部依赖,最好能够容纳Crontab的所有基本功能,那么Schedule模块是你的不二之选。

使用它来调度任务可能只需要几行代码,感受一下:

# Python 实用宝典
import schedule
import time

def job():
    print("I'm working...")

schedule.every(10).minutes.do(job)

while True:
    schedule.run_pending()
    time.sleep(1)

上面的代码表示每10分钟执行一次job函数,非常简单方便。你只需要引入schedule模块,通过调用 `scedule.every(时间数).时间类型.do(job)` 发布周期任务。

发布后的周期任务需要用 run_pending 函数来检测是否执行,因此需要一个While循环不断地轮询这个函数。

下面具体讲讲Schedule模块的安装和初级、进阶使用方法。

1.准备

开始之前,你要确保Python和pip已经成功安装在电脑上,如果没有,请访问这篇文章:超详细Python安装指南 进行安装。

(可选1) 如果你用Python的目的是数据分析,可以直接安装Anaconda:Python数据分析与挖掘好帮手—Anaconda,它内置了Python和pip.

(可选2) 此外,推荐大家用VSCode编辑器来编写小型Python项目:Python 编程的最好搭档—VSCode 详细指南

Windows环境下打开Cmd(开始—运行—CMD),苹果系统环境下请打开Terminal(command+空格输入Terminal),输入命令安装依赖:

pip install schedule

2.Schedule 基本使用

最基本的使用在文首已经提到过,下面给大家展示更多的调度任务例子:

# Python 实用宝典
import schedule
import time

def job():
    print("I'm working...")

# 每十分钟执行任务
schedule.every(10).minutes.do(job)
# 每个小时执行任务
schedule.every().hour.do(job)
# 每天的10:30执行任务
schedule.every().day.at("10:30").do(job)
# 每个月执行任务
schedule.every().monday.do(job)
# 每个星期三的13:15分执行任务
schedule.every().wednesday.at("13:15").do(job)
# 每分钟的第17秒执行任务
schedule.every().minute.at(":17").do(job)

while True:
    schedule.run_pending()
    time.sleep(1)

可以看到,从月到秒的配置,上面的例子都覆盖到了。不过如果你想只运行一次任务的话,可以这么配:

# Python 实用宝典
import schedule
import time

def job_that_executes_once():
    # 此处编写的任务只会执行一次...
    return schedule.CancelJob

schedule.every().day.at('22:30').do(job_that_executes_once)

while True:
    schedule.run_pending()
    time.sleep(1)

参数传递

如果你有参数需要传递给作业去执行,你只需要这么做:

# Python 实用宝典
import schedule

def greet(name):
    print('Hello', name)

# do() 将额外的参数传递给job函数
schedule.every(2).seconds.do(greet, name='Alice')
schedule.every(4).seconds.do(greet, name='Bob')

获取目前所有的作业

如果你想获取目前所有的作业,可以这么做:

# Python 实用宝典
import schedule

def hello():
    print('Hello world')

schedule.every().second.do(hello)

all_jobs = schedule.get_jobs()

取消所有作业

如果某些机制触发了,你需要立即清除当前程序的所有作业,需要这么使用:

# Python 实用宝典
import schedule

def greet(name):
    print('Hello {}'.format(name))

schedule.every().second.do(greet)

schedule.clear()

标签功能

在设置作业的时候,为了后续方便管理作业,你可以给作业打个标签,这样你可以通过标签过滤获取作业或取消作业。

# Python 实用宝典
import schedule

def greet(name):
    print('Hello {}'.format(name))

# .tag 打标签
schedule.every().day.do(greet, 'Andrea').tag('daily-tasks', 'friend')
schedule.every().hour.do(greet, 'John').tag('hourly-tasks', 'friend')
schedule.every().hour.do(greet, 'Monica').tag('hourly-tasks', 'customer')
schedule.every().day.do(greet, 'Derek').tag('daily-tasks', 'guest')

# get_jobs(标签):可以获取所有该标签的任务
friends = schedule.get_jobs('friend')

# 取消所有 daily-tasks 标签的任务
schedule.clear('daily-tasks')

设定作业截止时间

如果你需要让某个作业到某个时间截止,你可以通过这个方法:

# Python 实用宝典
import schedule
from datetime import datetime, timedelta, time

def job():
    print('Boo')

# 每个小时运行作业,18:30后停止
schedule.every(1).hours.until("18:30").do(job)

# 每个小时运行作业,2030-01-01 18:33 today
schedule.every(1).hours.until("2030-01-01 18:33").do(job)

# 每个小时运行作业,8个小时后停止
schedule.every(1).hours.until(timedelta(hours=8)).do(job)

# 每个小时运行作业,11:32:42后停止
schedule.every(1).hours.until(time(11, 33, 42)).do(job)

# 每个小时运行作业,2020-5-17 11:36:20后停止
schedule.every(1).hours.until(datetime(2020, 5, 17, 11, 36, 20)).do(job)

截止日期之后,该作业将无法运行。

立即运行所有作业,而不管其安排如何

如果某个机制触发了,你需要立即运行所有作业,可以调用 schedule.run_all() :

# Python 实用宝典
import schedule

def job_1():
    print('Foo')

def job_2():
    print('Bar')

schedule.every().monday.at("12:40").do(job_1)
schedule.every().tuesday.at("16:40").do(job_2)

schedule.run_all()

# 立即运行所有作业,每次作业间隔10秒
schedule.run_all(delay_seconds=10)

3.高级使用

装饰器安排作业

如果你觉得设定作业这种形式太啰嗦了,也可以使用装饰器模式:

# Python 实用宝典
from schedule import every, repeat, run_pending
import time

# 此装饰器效果等同于 schedule.every(10).minutes.do(job)
@repeat(every(10).minutes)
def job():
    print("I am a scheduled job")

while True:
    run_pending()
    time.sleep(1)

并行执行

默认情况下,Schedule 按顺序执行所有作业。其背后的原因是,很难找到让每个人都高兴的并行执行模型。

不过你可以通过多线程的形式来运行每个作业以解决此限制:

# Python 实用宝典
import threading
import time
import schedule

def job1():
    print("I'm running on thread %s" % threading.current_thread())
def job2():
    print("I'm running on thread %s" % threading.current_thread())
def job3():
    print("I'm running on thread %s" % threading.current_thread())

def run_threaded(job_func):
    job_thread = threading.Thread(target=job_func)
    job_thread.start()

schedule.every(10).seconds.do(run_threaded, job1)
schedule.every(10).seconds.do(run_threaded, job2)
schedule.every(10).seconds.do(run_threaded, job3)

while True:
    schedule.run_pending()
    time.sleep(1)

日志记录

Schedule模块同时也支持logging日志记录,这么使用:

# Python 实用宝典
import schedule
import logging

logging.basicConfig()
schedule_logger = logging.getLogger('schedule')
# 日志级别为DEBUG
schedule_logger.setLevel(level=logging.DEBUG)

def job():
    print("Hello, Logs")

schedule.every().second.do(job)

schedule.run_all()

schedule.clear()

效果如下:

DEBUG:schedule:Running *all* 1 jobs with 0s delay in between
DEBUG:schedule:Running job Job(interval=1, unit=seconds, do=job, args=(), kwargs={})
Hello, Logs
DEBUG:schedule:Deleting *all* jobs

异常处理

Schedule不会自动捕捉异常,它遇到异常会直接抛出,这会导致一个严重的问题:后续所有的作业都会被中断执行,因此我们需要捕捉到这些异常。

你可以手动捕捉,但是某些你预料不到的情况需要程序进行自动捕获,加一个装饰器就能做到了:

# Python 实用宝典
import functools

def catch_exceptions(cancel_on_failure=False):
    def catch_exceptions_decorator(job_func):
        @functools.wraps(job_func)
        def wrapper(*args, **kwargs):
            try:
                return job_func(*args, **kwargs)
            except:
                import traceback
                print(traceback.format_exc())
                if cancel_on_failure:
                    return schedule.CancelJob
        return wrapper
    return catch_exceptions_decorator

@catch_exceptions(cancel_on_failure=True)
def bad_task():
    return 1 / 0

schedule.every(5).minutes.do(bad_task)

这样,bad_task在执行时遇到的任何错误,都会被catch_exceptions捕获,这点在保证调度任务正常运转的时候非常关键。

我们的文章到此就结束啦,如果你喜欢今天的 Python 教程,请持续关注Python实用宝典。

有任何问题,可以在公众号后台回复:加群,回答相应验证信息,进入互助群询问。

原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!

给作者打赏,选择打赏金额
¥1¥5¥10¥20¥50¥100¥200 自定义

​Python实用宝典 ( pythondict.com )
不只是一个宝典
欢迎关注公众号:Python实用宝典

Python 调用 Shodan 实战教程 — 互联网上最可怕的搜索引擎

Shodan 在百度百科里被给出了这么一句话介绍:Shodan是互联网上最可怕的搜索引擎。

为什么呢?与谷歌、百度等搜索引擎爬取网页信息不同,Shodan爬取的是互联网上所有设备的IP地址及其端口号。

而随着智能家电的普及,家家户户都有许多电器连接到互联网,这些设备存在被入侵的可能性,这是十分危险的。

说了这么多,给大家体验下shodan,让你们有更切身的理解。打开shodan,在搜索框输入 Hikvision-Webs:

你会搜素到这个品牌的摄像头设备遍及全球的IP及其暴露的端口号:

可以看到,这台机器暴露了17、80、111、995、3128、5000、6000、20547端口,黑客可以根据这些端口进行针对性的攻击。

不过也不需要过于担心,如果你的服务不存在漏洞,一般是无法攻入的。但有些端口号会暴露摄像头的web管理端,如下:

那么黑客可能可以用暴力破解的方式,强行进入摄像头后台管理端,获取到实时的录像。

谨记这会侵犯别人的隐私权,是违法的行为,我们是遵纪守法的好公民所以知道它的原理和危害就足够。我们的目的是运用技术保护好个人隐私,如非必要不将摄像头接入互联网,一定要接入的话,不能使用容易被破解的弱口令。

Shodan Web端非常好用,但如果我们有从Python搜索的需求怎么办?

没关系,shodan 官方也提供了python官方SDK包,下面就来讲讲这个SDK包的使用。

1.准备

开始之前,你要确保Python和pip已经成功安装在电脑上,如果没有,请访问这篇文章:超详细Python安装指南 进行安装。

(可选1) 如果你用Python的目的是数据分析,可以直接安装Anaconda:Python数据分析与挖掘好帮手—Anaconda,它内置了Python和pip.

(可选2) 此外,推荐大家用VSCode编辑器来编写小型Python项目:Python 编程的最好搭档—VSCode 详细指南

Windows环境下打开Cmd(开始—运行—CMD),苹果系统环境下请打开Terminal(command+空格输入Terminal),输入命令安装依赖:

pip install shodan

2.Shodan 注册账号获取API

使用 Shodan 必须注册账号,注册网址https://account.shodan.io/register

输入完相关信息,点击 CREATE 会跳转到个人账户页:

此时 API Key 会显示你的API秘钥,请记录这个秘钥,后续会使用到这个秘钥去请求接口。

3.Shodan 基本调用实战教程

Shodan本质上就是一个搜索引擎,你只需要输入搜索的关键词:

# 公众号:Python 实用宝典
# 2021-05-04
from shodan import Shodan

api = Shodan('你的API KEY')

def search_shodan(keyword):
    # 调用搜索接口
    result = api.search(keyword)

    # 显示所有IP
    for service in result['matches']:
            print(service['ip_str'])

search_shodan("Hikvision-Webs")

结果如下:

可惜的是,普通API只能像这样搜索关键字,无法使用过滤条件如:Hikvision-Webs country:”US” 搜索美国内的所有Hikvision网站管理端。

如果你想要使用过滤条件,Shodan需要你升级API权限:

挺贵的,不过还好是一次性支付,永久使用。

4. Shodan 高级使用教程

Shodan 的用处当然不仅仅是在黑客攻防中,它还能用于统计。如果你想要了解哪些国家的使用这款摄像头的数量最多,可以使用 Facets 特性。

# 公众号:Python 实用宝典
# 2021-05-04
from shodan import Shodan

api = Shodan('你的API KEY')
def try_facets(query):
    FACETS = [
        'org',
        'domain',
        'port',
        'asn',
        ('country', 3),
    ]

    FACET_TITLES = {
        'org': 'Top 5 Organizations',
        'domain': 'Top 5 Domains',
        'port': 'Top 5 Ports',
        'asn': 'Top 5 Autonomous Systems',
        'country': 'Top 3 Countries',
    }

    try:
        # 使用 count() 方法可以不需要升级API,且比 search 方法更快。
        result = api.count(query, facets=FACETS)

        print('Shodan Summary Information')
        print('Query: %s' % query)
        print('Total Results: %s\n' % result['total'])

        # 显示每个要素的摘要
        for facet in result['facets']:
            print(FACET_TITLES[facet])

            for term in result['facets'][facet]:
                print('%s: %s' % (term['value'], term['count']))

    except Exception as e:
        print('Error: %s' % e)

try_facets("Hikvision-Webs")

得到结果如下:

从 Top 3 Countries 中可以看到,这款摄像头使用数量排名前三的国家分别是:美国、日本和德国。

没想到吧,Shodan居然还能用于产品分析。同样地原理,如果你把关键词改为”apache”,你可以知道目前哪些国家使用apache服务器数量最多,最普遍被使用的版本号是什么。

简而言之,Shodan是一个非常强大的搜索引擎,它在好人手里,能被发挥出巨大的潜能。如果Shodan落入坏人之手的话,那真是一个可怕的东西。

为了避免受到不必要的攻击,请大家及时检查所有联网设备的管理端的密码,如果有使用默认密码及弱口令,立即进行密码的更改,以保证服务的安全。

本文所有源代码可在 Python 实用宝典 公众号后台回复:shodan 下载。

我们的文章到此就结束啦,如果你喜欢今天的 Python 教程,请持续关注Python实用宝典。

有任何问题,可以在公众号后台回复:加群,回答相应验证信息,进入互助群询问。

原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!

给作者打赏,选择打赏金额
¥1¥5¥10¥20¥50¥100¥200 自定义

​Python实用宝典 ( pythondict.com )
不只是一个宝典
欢迎关注公众号:Python实用宝典

Python 超强大的PDF表格提取器 — Camelot

如果你有从PDF中批量提取表格的需求,那么这篇文章就是你的福音。

Python 第三方模块 Camelot 能够精准识别PDF中的表格信息,并提取为pandas数据结构,而且还能导出为多种格式:JSON,Excel,HTML和Sqlite。

下面给大家介绍这个模块的使用方法:

1.准备

开始之前,你要确保Python和pip已经成功安装在电脑上,如果没有,请访问这篇文章:超详细Python安装指南 进行安装。

(可选1) 如果你用Python的目的是数据分析,可以直接安装Anaconda:Python数据分析与挖掘好帮手—Anaconda,它内置了Python和pip.

(可选2) 此外,推荐大家用VSCode编辑器来编写小型Python项目:Python 编程的最好搭档—VSCode 详细指南

Windows环境下打开Cmd(开始—运行—CMD),苹果系统环境下请打开Terminal(command+空格输入Terminal),输入命令安装依赖:

pip install camelot-py[cv]

2.使用

最简单的使用方式如下:

import camelot
# 1.读取pdf
tables = camelot.read_pdf('foo.pdf', flavor='stream')
# 2.导出pdf所有的表格为csv文件
tables.export('foo.csv', f='csv') # json, excel, html, sqlite

第一行,导入了camelot这个模块。

第二行,以stream的模式读取当前目录的foo.pdf文件。

第三行,将所有表格数据导出为 foo.csv 文件,并保存在当前文件夹下。

相当简单,请注意,read_pdf 的 flavor 参数是可选的,如果你不带这个参数,请注意需要安装 ghostscript 这个驱动,因为它默认使用 ghostscript 去用 lattice 模式。

3.进阶

3.1 处理背景线:

可以看到,很多表格的线都隐藏在背景中。这种表格默认是不支持的,这时候我们需要让程序能够自动识别这样的表格:

tables = camelot.read_pdf('background_lines.pdf', process_background=True)

增加 process_background=True 参数即可。

3.2 指定表格区域

某些情况下无法正确识别到PDF中的表格,此时手动设定左上角和右下角的边界可能是有效果的:

tables = camelot.read_pdf('table_areas.pdf', flavor='stream', table_areas=['316,499,566,337'])

其中 table_areas 接受格式为 x1,y1,x2,y2 的字符串,其中(x1,y1) -> 左上角, (x2,y2) -> 右下角。在PDF坐标空间中,页面的左下角是原点,坐标为(0,0)。

本文的代码和示例,以及Camelot源仓库可在 Python实用宝典 公众号后台回复 camelot 下载。

我们的文章到此就结束啦,如果你喜欢今天的 Python 教程,请持续关注Python实用宝典。

有任何问题,可以在公众号后台回复:加群,回答相应验证信息,进入互助群询问。

原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!

给作者打赏,选择打赏金额
¥1¥5¥10¥20¥50¥100¥200 自定义

​Python实用宝典 ( pythondict.com )
不只是一个宝典
欢迎关注公众号:Python实用宝典

py-spy:Python 程序的性能监控器

py-spy是用于Python程序的性能监控器。它使你可以直观地看到Python程序花费的时间,而无需重新启动程序或以任何方式修改代码。

py-spy的开销非常低:为了最大化提高速度,它是用Rust编写的,并且与配置的Python程序不在同一进程中运行。这意味着 py-spy 可以安全地用于生产环境的Python程序。

py-spy 可在 Linux,OSX,Windows 和 FreeBSD 上运行,并支持所有最新版本的CPython解释器(2.3-2.7和3.3-3.8版)进行性能分析。

1.安装

可以通过以下方式从 PyPI 安装预构建的二进制wheel文件:

pip install py-spy

你也可以从 GitHub Release Page 下载预构建的二进制文件,如果网络无法连接GitHub,你也可在 Python实用宝典 公众号后台回复 pyspy 下载。

2.用法

py-spy 在命令行中进行工作,获取你要从监控的程序的PID或你要运行的python程序的文件。分别有三种分析方法  recordtop以及dump

record

py-spy支持使用record命令将配置文件记录到文件中。例如,您可以通过执行以下操作来生成python进程的热力图

py-spy record -o profile.svg --pid 12345
# OR
py-spy record -o profile.svg -- python myprogram.py

它将生成一个交互式SVG文件,如下所示:

你可以使用参数 –format 更改文件格式。请参阅参考资料,py-spy record --help 以获取有关其他选项的信息,包括更改采样率,仅包含GIL的线程进行过滤,对本机C扩展进行概要分析,显示线程ID,概要分析子进程等。

Top

Top显示了在python程序中花费最多时间的函数的实时视图,类似于Unix top命令。使用以下命令运行:

py-spy top --pid 12345
# OR
py-spy top -- python myprogram.py

将显示你的python程序的实时函数消耗:

Dump

py-spy 还可以使用 dump 命令显示每个 python 线程的当前调用堆栈:

py-spy dump --pid 12345

这会将每个线程的调用堆栈以及其他一些基本进程信息转发到控制台:

对于需要一个调用堆栈来确定python程序挂在何处的情况,这很有用。该命令还可以通过设置 --locals 标志来打印出与每个堆栈帧关联的局部变量。

我们的文章到此就结束啦,如果你喜欢今天的 Python 教程,请持续关注Python实用宝典。

有任何问题,可以在公众号后台回复:加群,回答相应验证信息,进入互助群询问。

原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!

给作者打赏,选择打赏金额
¥1¥5¥10¥20¥50¥100¥200 自定义

​Python实用宝典 ( pythondict.com )
不只是一个宝典
欢迎关注公众号:Python实用宝典

Python 超方便的迭代进度条 (Tqdm)

Tqdm 是一个智能进度表。它能够显示所有可迭代对象当前执行的进度。

你只需要用 tqdm 对可迭代对象进行封装后再遍历即可实现进度条功能,比如说:

from tqdm import tqdm
for i in tqdm(range(10000)):
    ...

显示效果如下:

76%|████████████████████████ | 7568/10000 [00:33<00:10, 229.00it/s]

1.准备

开始之前,你要确保Python和pip已经成功安装在电脑上,如果没有,请访问这篇文章:超详细Python安装指南 进行安装。

(可选1) 如果你用Python的目的是数据分析,可以直接安装Anaconda:Python数据分析与挖掘好帮手—Anaconda,它内置了Python和pip.

(可选2) 此外,推荐大家用VSCode编辑器来编写小型Python项目:Python 编程的最好搭档—VSCode 详细指南

Windows环境下打开Cmd(开始—运行—CMD),苹果系统环境下请打开Terminal(command+空格输入Terminal),输入命令安装依赖:

pip install tqdm

2.基本使用

tqdm 非常灵活,可以使用多种方式调用。下面给出了三个主要的形式。

2.1 迭代的形式

使用tqdm()封装可迭代的对象:

from tqdm import tqdm
from time import sleep

text = ""
for char in tqdm(["a", "b", "c", "d"]):
    sleep(0.25)
    text = text + char

trange(i)是特殊的关键字,是封装了range的tqdm对象:

from tqdm import trange

for i in trange(100):
    sleep(0.01)

你还能控制进度条显示当前步骤的名称:

pbar = tqdm(["a", "b", "c", "d"])
for char in pbar:
    sleep(0.25)
    pbar.set_description("Processing %s" % char)

Processing d: 100%|█████████████████████████████████████████████| 4/4 [00:01<00:00, 3.99it/s]

2.2 手动的形式

除了迭代的形式,你可以手动控制进度,加一个tqdm上下文即可:

with tqdm(total=100) as pbar:
    for i in range(10):
        sleep(0.1)
        pbar.update(10)

上述例子中,pbar 是 tpdm 的“进度”,每一次对 pbar 进行 update 10 都相当于进度加10。

Total 的值即是总进度,这里 total 的值是100,那么pbar加到100的时候进度也就结束了。

你也可以选择不使用上下文的形式调用,但要记得结束后对对象进行关闭操作:

pbar = tqdm(total=100)
for i in range(10):
    sleep(0.1)
    pbar.update(10)
pbar.close()

3.模块结合

Tqdm 最妙的地方在于能在命令行中结合使用:

$ find . -name '*.py' -type f -exec cat \{} \; |
    tqdm --unit loc --unit_scale --total 857366 >> /dev/null
100%|█████████████████████████████████| 857K/857K [00:04<00:00, 246Kloc/s]

只需在管道之间插入tqdm(或python -m tqdm),即可将进度条显示到终端上。

备份大目录:

$ tar -zcf - docs/ | tqdm --bytes --total `du -sb docs/ | cut -f1` \
  > backup.tgz
 44%|██████████████▊                   | 153M/352M [00:14<00:18, 11.0MB/s]

这可以进一步美化:

$ BYTES="$(du -sb docs/ | cut -f1)"
$ tar -cf - docs/ \
  | tqdm --bytes --total "$BYTES" --desc Processing | gzip \
  | tqdm --bytes --total "$BYTES" --desc Compressed --position 1 \
  > ~/backup.tgz
Processing: 100%|██████████████████████| 352M/352M [00:14<00:00, 30.2MB/s]
Compressed:  42%|█████████▎            | 148M/352M [00:14<00:19, 10.9MB/s]

我们的文章到此就结束啦,如果你喜欢今天的 Python 教程,请持续关注Python实用宝典。

有任何问题,可以在公众号后台回复:加群,回答相应验证信息,进入互助群询问。

原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!

给作者打赏,选择打赏金额
¥1¥5¥10¥20¥50¥100¥200 自定义

​Python实用宝典 ( pythondict.com )
不只是一个宝典
欢迎关注公众号:Python实用宝典

阿里Python 自动化工具 tidevice 使用指南

1. 前言

最近,阿里内部开源了一个 iOS 端由 Python 编写的自动化工具,即:tidevice

它是一款跨平台的自动化开源工具,不依赖 Xcode 就可以启动 WebDriverAgent( WDA ),这也就意味着 Windows 可以直接运行 iOS 自动化脚本

项目地址:

https://github.com/alibaba/taobao-iphone-device

2. 准备

进入到虚拟环境,先安装 tidevice 的依赖包

# 安装依赖包
pip3 install -U "tidevice[openssl]" 

# 查看tidevice版本,检查是否安装成功
tidevice version

3. 常见功能

将 iPhone 设备连接到电脑上,就可以使用 tidevice 提供的功能了

3-1  查看设备列表

# 二选一
tidevice list

# json数据显示
tidevice list --json

3-2  安装、卸载应用

安装对应的关键字为:「 install

tidevice 同时支持安装本地 ipa 包和远链下的 ipa 应用包

另外,tidevice 可以使用「 –udid 」参数将应用安装到某一台设备中

# 安装本地应用
tidevice install example.ipa

# 根据udid参数,指定设备安装应用
tidevice --udid $UDID install https://example.org/example.ipa
tidevice install https://.....ipa

卸载对应的关键字为:「 uninstall

通过应用包名可以卸载设备上的某一个应用

# 卸载应用(通过包名)
# 比如:知识星球App包名为:com.unnoo.quan
tidevice uninstall com.unnoo.quan

3-3  启动、关闭应用

启动应用对应的关键字为:「 launch

关闭应用对应的关键字为:「 kill

# 打开应用
tidevice launch com.unnoo.quan

# 停止杀死应用
tidevice kill com.unnoo.quan

3-4  已安装应用及名称、版本

使用「 tidevice applist 」命令,可以查看设备上已经安装的应用、应用名称、应用版本号

# 查看设备应用信息列表
localhost:tidevice_demo xingag
 
nbsp;tidevice applist
com.tencent.xin WeChat 8.0.2
com.ss.iphone.ugc.Aweme 抖音 13.4.0
com.tencent.mttlite QQ浏览器 10.8.3
com.panasonic.jp.imageapp Image App 1.10.17
com.unnoo.quan 知识星球 4.20.2
co.visualsupply.cam VSCO 189
com.ucweb.iphone.lowversion UC浏览器 13.1.5
com.niksoftware.snapseedforipad Snapseed 2.19.5
com.autonavi.amap 高德地图 10.76.0
com.lagou.education 拉勾教育 1.4.9
com.xunmeng.pinduoduo 拼多多 5.37.0
com.tencent.QQMusic QQ音樂 10.5.5
io.ideamp.feelcab Feelca B 1.6.0
com.chinaunicom.mobilebusiness 手机营业厅 8.00.01
com.feiyu-tech.vico Vicool 1.2.26
com.ss.iphone.article.News 今日头条 7.9.3
com.sogou.sogouinput 搜狗输入法 10.18.1
org.geekbang.GeekTime 极客时间 2.9.2
com.burbn.hyperlapse Hyperlapse 1.3.4
com.apple.itunesu iTunes U 3.8

3-5  设备信息

利用「 tidevice info 」可以查看设备信息,比如:设备序列号、系统版本、CPU、本机号码、时间戳、蓝牙地址、MAC 地址等信息

# 查看设备信息
localhost:~ xingag
 
nbsp;tidevice info
MarketName:       iPhone SE (1st generation)
DeviceName:       xingag
ProductVersion:   14.4
ProductType:      iPhone8,4
ModelNumber:      MP892
SerialNumber:     ...
CPUArchitecture:  arm64
ProductName:      iPhone OS
ProtocolVersion:  2
RegionInfo:       ZP/A
TimeIntervalSince1970: 1616979424.235399
TimeZone:         Asia/Shanghai
WiFiAddress:      58:e2:8f:68:4c:b0
BluetoothAddress: 58:e2:8f:68:4c:b1
BasebandVersion:  10.40.01
...

如果要查看设备的电池信息,可以使用关键字 「 –domain + 应用包名 」来获取

# 查看设备电池信息
localhost:~ xingag
 
nbsp;tidevice info --domain com.apple.mobile.battery --json
{
    "BatteryCurrentCapacity"54,
    "BatteryIsCharging"true,
    "ExternalChargeCapable"true,
    "ExternalConnected"true,
    "FullyCharged"false,
    "GasGaugeCapability"true,
    "HasBattery"true
}

3-6  重启及截图

重启对应的关键字为:「 reboot

截图对应的关键字为:「 screenshot

# 重启设备
tidevice reboot

# 截图并保存到文件 screenshot.jpg 中
tidevice screenshot screenshot.jpg

3-7  系统日志及更多帮助

查看系统日志的命令为:「 tidevice syslog 」,当然也可以配置 grep 参数进行过滤 

# 查看系统日志
tidevice syslog

# 更多帮助
tidevice -h

4. 自动化步骤

要完成 iOS 端的自动化,我们还需要做一些准备工作

4-1 安装 WDA

我们需要将 WebDriverAgent 安装到 iOS 设备上,通过它驱动手机进行一系列自动化操作

PS:由于 Facebook WDA 很长时间没有更新了,这里建议直接使用 Appium WDA

https://github.com/appium/WebDriverAgent

下载项目后,使用 Xcode 打开,Scheme 选择 WebDriverAgentRunner,设备选择真机

然后配置开发者证书,可以参考下面链接进行配置

https://testerhome.com/topics/7220

最后,Xcode 选择 Project 下的 Test 将项目运行到真机设备上

注意:第一次运行 WDA 可能运行失败,需要手动在设置中对证书添加信任

4-2  运行 WDA

真机设备安装完 WDA 后,就可以脱离 Mac,使用 Windows 进行自动化操作了

使用「 tidevice wdaproxy 」命令可以运行 WDA 和端口转发

 # 运行 WDA
# 端口转发到8100
# 应用包名:com.facebook.WebDriverAgentRunner.xingag23.xctrunner
idevice wdaproxy -B com.facebook.WebDriverAgentRunner.xingag23.xctrunner --port 8100

PS:由于 Xcode 设置证书的时候,更改过 bundle_id,所以这里的包名是一个变量

4-3  编写自动化脚本

接下来,就可以使用 Appium 或 facebook-wda 编写脚本并运行到 iOS 设备上了

以 facebook-wda 为例

首先,我们安装对应的依赖

# 安装facebook-wda依赖
pip3 install -U facebook-wda

接着,编写自动化脚本并运行测试

import wda
import time

# 连接设备
c1 = wda.USBClient()

# c1 = wda.Client("http://10.3.209.175:8100")
print(c.info)

# 极客时间
bundle_id = 'org.geekbang.GeekTime'

# 通过app的bundleId启动App
s = c1.session(bundle_id)

# 休眠5s
s.sleep(5)

# 截图保存到本地
c1.screenshot('sc.png')

# 回到桌面
s.home()

5. 最后

阿里这款 iOS 端自动化工具的主要优点是启动速度快,内存占用低;更重要的是,它是跨平台,稳定性相对较高

如果你觉得文章还不错,请大家 点赞、分享、留言 下,因为这将是我持续输出更多优质文章的最强动力!

本文转自Airpython.

我们的文章到此就结束啦,如果你喜欢今天的 Python 教程,请持续关注Python实用宝典。

有任何问题,可以在公众号后台回复:加群,回答相应验证信息,进入互助群询问。

原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!

给作者打赏,选择打赏金额
¥1¥5¥10¥20¥50¥100¥200 自定义

​Python实用宝典 ( pythondict.com )
不只是一个宝典
欢迎关注公众号:Python实用宝典