ZoomEye-python工具使用详解(二)

本文涉及的产品
.cn 域名,1个 12个月
简介: ZoomEye-python工具使用详解(二)

接上文 ZoomEye-python工具使用详解(一)https://developer.aliyun.com/article/1618398

6. 数据筛选
使用-filter参数查询数据结果集里的部分片段的列表,或者基于内容进行筛选。这个命令支持的片段包括:

# host/search
app                 显示应用类型详情
version            显示版本信息详情
device            显示设备类型详情
port                显示端口信息详情
city                显示城市详情
country            显示国家详情
asn                    显示as number详情
banner            显示特性响应的详情
timestamp        显示数据事件的记录
*                        当这个标识被包含,显示所有字段的详情


# web/search
app                    显示应用类型详情
headers            HTTP头
keywords        meta关键字
title                HTTP Title信息
site                 站点搜索
city                 显示城市详情
country            显示国家详情
webapp            Web应用
component        Web容器
framework        Web框架
server            Web服务器
waf                 Web防火墙(WAF)
os                    操作系统
timestamp        更新时间戳
*                        当这个标识被包含,显示所有字段的详情

对比默认条件下的省略显示,完整的数据能够通过-filter被浏览,如下:

(base) liuxiaowei@MacBookAir ~ % zoomeye search 'telnet' -num 1 -filter banner
ip                            banner                        
61.*.*.78                  \xff\xfb,\xff\xfb\x03\xff\xfb\x01\xff\xfb\x00\xff\xfd\x00\r\n*\r\n* * * ttyS7 is being used by (none) !!!\r\n*\r\n
total: 1

当使用-filter进行筛选,语法是:key1, key2, key3=value, where “key3=value”是筛选条件 而且被显示的内容是key1, key2,例如:

(base) liuxiaowei@MacBookAir ~ % zoomeye search telnet -num 1 -filter port,app,banner=Telnet
ip                            port                          app                           
27.*.*.225                8000                          MikroTik router config httpd  

total: 1

在上面的例子里:“banner=Telnet”是一个筛选条件,而port,app是显示内容。如果你需要显示banner,筛选语句像如下这样:

(base) liuxiaowei@MacBookAir ~ % zoomeye search telnet -num 1 -filter port,app,anner,banner=Telnet
ip                            port                          app                           banner                        
27.*.*.225                8000                          MikroTik router config httpd  HTTP/1.0 200 OK\r\nConnection: close\r\nContent-Length: 7065\r\nContent-Type: text/html\r\nDate: Mon, 25 Apr 2022 22:05:56 GMT\r\nExpires: 0\r\n\r\n<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\r\n<html xmlns="http://www.w3.org/1999/xhtml">\r\n<head>\r\n<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />\r\n<link rel="icon" href="/favicon.png"/>\r\n<title>RouterOS router configuration page</title>\r\n<style type="text/css">\r\nbody {
   \r\nfont-family: Verdana, Geneva, sans-serif;\r\nfont-size: 11px;\r\n}\r\nimg {
   border: none}\r\nimg:hover {
   opacity: 0.8;}\r\nh1 {
   \r\nfont-size: 1.7em;\r\ndisplay: inline;\r\nmargin-bottom: 10px;\r\n}\r\nfieldset {
   \r\nmargin-top: 20px;\r\nbackground: #fff;\r\npadding: 20px;\r\nborder: 1px solid #c1c1c1; \r\n}\r\n#container {
   \r\nwidth: 70%;\r\nmargin: 10% auto;\r\n}\r\n#box {
   \r\nbackground-color: #fff; \r\n-moz-border-radius: 7px; \r\n-webkit-border-radius: 7px; \r\nborder: 1px solid #c1c1c1; \r\npadding: 30px;\r\nfilter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#f3f3f3'); /* for IE */\r\nbackground: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#f3f3f3)); /* for webkit browsers */\r\nbackground: -moz-linear-gradient(top,  #fff,  #f3f3f3); /* for firefox 3.6+ */\r\n}\r\n.floater {
   float: left; margin-right: 10px;}\r\n.floater label {
   display: block; text-align: center;}\r\n\r\n#login {
   \r\n    margin: 2em 0 4em 0;\r\n}\r\n#login h2 {
   \r\n    font-weight: normal;\r\n    font-size: 14px;\r\n    margin: 0 0 0.5em 1em;\r\n}\r\n#login td {
   \r\n    padding: 0 4px 0 0;\r\n}\r\n#login td.label {
   \r\n    text-align: right;\r\n}\r\n#login td.toolbar {
   \r\n    padding: 0 0 0 1em;\r\n    vertical-align: top;\r\n}\r\n#login ul.toolbar {
   \r\n    margin: 0;\r\n}\r\n#login input {
   \r\n    margin: 2px;\r\n    padding: 2px;\r\n    border: 1px solid #888;\r\n    box-shadow: 1px 1px 3px rgba(0,0,0,0.3);\r\n    -webkit-box-shadow: 1px 1px 3px rgba(0,0,0,0.3);\r\n    -moz-box-shadow: 1px 1px 3px rgba(0,0,0,0.3);\r\n}\r\n#error {
   \r\n    display:none;\r\n    color:red;\r\n    padding: 1em 0 0 0;\r\n}\r\nul.toolbar {
   \r\n    font-size: 11px;\r\n    text-align: left;\r\n    list-style-type: none;\r\n    padding: 0;\r\n    margin: 2px 0 4px 2px;\r\n}\r\nul.toolbar li {
   \r\n    float: left;\r\n    vertical-align: middle;\r\n}\r\nul.toolbar a {
   \r\n    float: none;\r\n    display: block;\r\n    margin: 2px 4px 2px 0;\r\n    padding: 5px;\r\n\r\n    background: #ddd;\r\n    border: 1px solid #888;\r\n    border-radius: 3px;\r\n    -moz-border-radius: 3px;\r\n    box-shadow:\r\n        1px 1px 2px rgba(255,255,255,0.8) inset,\r\n\t0 10px 10px -5px rgba(255,255,255,0.5) inset, /* top gradient */\r\n\t1px 1px 2px rgba(0,0,0,0.2); /* shadow */\r\n    -webkit-box-shadow:\r\n        1px 1px 2px rgba(255,255,255,0.8) inset,\r\n\t0 10px 10px -5px rgba(255,255,255,0.5) inset,\r\n\t1px 1px 2px rgba(0,0,0,0.2);\r\n    -moz-box-shadow:\r\n        1px 1px 2px rgba(255,255,255,0.8) inset,\r\n\t0 10px 10px -5px rgba(255,255,255,0.5) inset,\r\n\t1px 1px 2px rgba(0,0,0,0.2);\r\n    color: #000;\r\n\r\n    text-decoration: none;\r\n    text-align: center;\r\n    white-space: nowrap;\r\n    cursor: inherit;\r\n    min-width: 4em;\r\n\r\n    -webkit-transition: background 0.2s linear, box-shadow 0.2s ease-out;\r\n    -moz-transition: background 0.2s linear, box-shadow 0.2s ease-out;\r\n}\r\nul.toolbar a:hover {
   \r\n    background: #eee;\r\n}\r\nul.toolbar a:active {
   \r\n    background: #aaa;\r\n    box-shadow: 1px 1px 2px #999 inset;\r\n    -webkit-box-shadow: 1px 1px 2px #999 inset;\r\n    -moz-box-shadow: 1px 1px 2px #999 inset;\r\n}\r\n</style>\r\n<script>\r\nfunction get(id) {
   \r\n    return document.getElementById(id);\r\n}\r\nfunction trim(str) {
   \r\n    return str.replace(/^\s+|\s+$/g, '');\r\n}\r\nfunction login(user, pwd, autologin) {
   \r\n    var expires = new Date();\r\n    expires.setTime(expires.getTime() + (30 * 24 * 60 * 60 * 1000));\r\n    document.cookie = 'username=' + user +\r\n        '; expires=' + expires.toGMTString() + '; path=/';\r\n\r\n    window.name = (autologin ? 'autologin=' : 'login=') + user + '|' + pwd;\r\n    window.location.replace('/webfig/' + window.location.hash);\r\n}\r\nfunction dologin() {
   \r\n    login(get('name').value, get('password').value);\r\n}\r\nfunction loaded() {
   \r\n    var p = window.name.split('=');\r\n    if (p[0] == 'error' && p[1]) {
   \r\n        var err = get('error');\r\n        err.appendChild(document.createTextNode(p[1]));\r\n        err.style.display = 'block';\r\n    } else if (p[0] != 'noautologin' || p[1] != 1) {
   \r\n        var user = '';\r\n        if (user) {
   \r\n            login(user, '', true);\r\n            return;\r\n        }\r\n    }\r\n    window.name = '';\r\n\r\n    document.onkeydown = function(e) {
   \r\n        e = e || event;\r\n        if (e.keyCode == 13) {
   \r\n            dologin();\r\n            return false;\r\n        }\r\n        return true;\r\n    };\r\n\r\n    var username = null;\r\n    var cookies = document.cookie.split(';');\r\n    for (var i in cookies) {
   \r\n\tvar c = trim(cookies[i]).split('=');\r\n\tif (c[0] == 'username') {
   \r\n\t    username = c[1];\r\n\t    break;\r\n\t}\r\n    }\r\n    \r\n    if (username != null) {
   \r\n\tget('name').value = username;\r\n\tget('password').focus();\r\n    } else {
   \r\n        get('name').value = 'admin';\r\n\tget('name').focus();\r\n    }\r\n}\r\n</script>\r\n</head>\r\n\r\n<body οnlοad="loaded()">\r\n\r\n<div id="container">\r\n\r\n    <div id="box">\r\n    <a href="http://mikrotik.com"><img src="mikrotik_logo.png" style="float: right;" /></a>\r\n\r\n    <br style="clear: both;"/>\r\n    \r\n\t\t<h1>RouterOS v6.45.7</h1>\r\n        \r\n        <p>You have connected to a router. Administrative access only. If this device is not in your possession, please contact your local network administrator. </p>\r\n        \r\n      <table id="login">\r\n\t<tr><td colspan="3"><h2>WebFig Login:</h2>\r\n        <tr><td class="label">Login: <td><input id="name" type="text" tabindex="1">\r\n\t <td class="toolbar" rowspan="2">\r\n         <ul class="toolbar">\r\n\t   <li><a οnclick="dologin()" οndragstart="return false;"><span>Login</span></a></li>\r\n         </ul>\r\n         <tr><td class="label">Password: <td><input id="password" type="password" tabindex="2">\r\n\t<tr><td colspan="3">\r\n\t    <div id="error"></div>\r\n      </table>\r\n            \r\n            <fieldset>\r\n            <div class="floater"> \r\n            \t<a href="http://www.mikrotik.com/download/winbox.exe"><img src="winbox.png"/></a><br/>\r\n                <label>Winbox</label>\r\n            </div>\r\n            \r\n            <div class="floater"> \r\n            \t<a href="telnet://27.106.108.225"><img src="console.png"/></a><br/>\r\n                <label>Telnet</label>\r\n            </div>\r\n\r\n            \r\n            \r\n            <div class="floater"> \r\n            \t<a href="/graphs"><img src="green.png"/></a><br/>\r\n                <label>Graphs</label>\r\n            </div>\r\n           \r\n            \r\n            <div class="floater"> \r\n            \t<a href="/help/license.html"><img src="license.png"/></a><br/>\r\n                <label>License</label>\r\n            </div>\r\n            \r\n\t\t\t<div class="floater"> \r\n            \t<a href="http://wiki.mikrotik.com"><img src="help.png"/></a><br/>\r\n                <label>Help</label>\r\n            </div>\r\n\r\n</fieldset>\r\n           \r\n            <br style="clear: both"/> \r\n                            <div style="float: right">© mikrotik</div>\r\n\r\n    </div>\r\n</div>\r\n\r\n</div>\r\n\r\n</body>\r\n</html>\r\n

total: 1

7. 数据输出
-save参数能够输出数据,这个参数的语法跟-filter一样。输出结果被存储为json行格式的文件,如下:

(base) liuxiaowei@MacBookAir ~ % zoomeye search 'telnet' -save banner=telnet
save file to /Users/liuxiaowei/telnet_8_1651301274.json successful!
(base) liuxiaowei@MacBookAir ~ % cat telnet_8_1651301274.json 
{
   'ip': '27.106.108.225'}
{
   'ip': '27.106.108.209'}
{
   'ip': '27.106.1.153'}
{
   'ip': '27.106.42.8'}
{
   'ip': '27.106.108.169'}
{
   'ip': '27.106.62.161'}
{
   'ip': '168.181.36.114'}
{
   'ip': '27.106.108.193'}

如果你使用-save不带任何参数,查询结果将被存储为ZoomEye API的json格式文件。这个方法通常当保留metadata的时候被用来整合数据;文件被当作输入,通过cli再次被解析和处理。类似zoomeye search ‘xxxxx.json’。

8. 图形化数据
-figure参数是一个数据可视化参数。这个参数提供两个显示方法:pie 饼图(pie cahrt)和hist 柱状图(histgoram)。没有指定它的时候数据依然被显示。当指定-figure的时候,只有图形将被显示。饼图如下:

(base) liuxiaowei@MacBookAir ~ % zoomeye search 'telnet' -figure pie -facet

image.png

(base) liuxiaowei@MacBookAir ~ % zoomeye search 'telnet' -figure  pie  -stat

image.png

柱状图如下:

(base) liuxiaowei@MacBookAir ~ % zoomeye search 'telnet' -figure  hist -facet

image.png

(base) liuxiaowei@MacBookAir ~ % zoomeye search 'telnet' -figure  hist -stat

image.png

备注:这个-figure参数只针对-facet, -stat两个查询参数有效

9. IP 历史
ZoomEye-python提供查询IP历史设备数据的功能。使用命令history [ip]查询IP设备的历史数据。用法如下:

(base) liuxiaowei@MacBookAir ~ % zoomeye history '27.*.1.153' -num 1

该项功能只对VIP用户开放。

(base) liuxiaowei@MacBookAir ~ % zoomeye history ip -h                
usage: zoomeye history [-h] [-filter [filed=regexp]] [-force] [-num value] ip

positional arguments:
  ip                    search historical device IP

optional arguments:
  -h, --help            show this help message and exit
  -filter [filed=regexp]
                        filter data and print raw data detail. field:
                        [timestamp,port,service,country,banner,*]
  -force                ignore the local cache and force the data to be obtained from the API
  -num value            The number of search results that should be returned

10. 搜索IP 信息
你可以通过zoom eye ip命令查询指定IP的目标信息,例如:

(base) liuxiaowei@MacBookAir ~ % zoomeye ip 27.*.62.161
Hostnames:                    [unknown]
Isp:                          joister.net
Country:                      India
City:                         Mumbai
Organization:                 Syscon Infoway Pvt. Ltd.
Lastupdated:                  2022-04-29T23:08:53
Number of open ports:         6{
   8000, 80, 81, 2000, 21, 1723}

port      service        app                    banner                        
21        ftp            MikroTik router ftpd   220 Core Router FTP ser...    
80        http           MikroTik router ...    HTTP/1.0 200 OK\r\nConn...    
81        http           MikroTik router ...    HTTP/1.0 200 OK\r\nConn...    
1723      pptp                                  pptp-info:\n\tFirmware:...    
2000      bandwidth-test MikroTik bandwid...    \x01\x00\x00\x00              
8000      https          MikroTik router ...    HTTP/1.0 200 OK\r\nConn...

Zoom eye ip命令也支持筛选参数-filter,语法和zoom eye searc 例子相同:

(base) liuxiaowei@MacBookAir ~ % zoomeye ip '27.106.62.161' -filter 'app,app=ntpd'
Hostnames:                    [unknown]
Isp:                          [unknown]
Country:                      Saudi Arabia
City:                         [unknown]
Organization:                 [unknown]
Lastupdated:                  2022-04-30T02:15:06
Number of open ports:         0
Number of historical probes:  1

app
ntpd

11. 清理功能
用户每天搜索大量的数据,这些数据会导致占有存储空间的缓存文件夹逐渐的增加。如果用户在公开服务器上使用ZoomEye-python,可能会导致他们自己的API KEY和ACCESS TOKEN泄漏。出于这个原因,ZoomEye-python提供一个清除命令zoomeye clear,可以清除缓存 数据和用户配置,用法如下:

(base) liuxiaowei@MacBookAir ~ % zoomeye clear -h
usage: zoomeye clear [-h] [-setting] [-cache]

optional arguments:
  -h, --help  show this help message and exit
  -setting    clear user api key and access token
  -cache      clear local cache file
(base) liuxiaowei@MacBookAir ~ % zoomeye clear -cache
clear complete!

12. 数据缓存
ZoomEye-python提供一个缓存在cli模式,位于~/.config/zoomeye/cache下,尽可能多的存储用户配额。用户查询的所有数据集将被本地缓存5天左右。当用户查询相同数据集的时候,配额不会被消耗。

注意:~/.config/zoomeye/settings文件夹下存储apikey和jwt

  1. 域名查询
    ZoomEye-python 提供了域名查询功能(包括香港的域名查询和子域名查询)。为了查询域名,运行域名查询命令如下所示:
(base) liuxiaowei@MacBookAir ~ % python cli.py domain baidu.com 0
name                                                   timestamp      ip
zszelle.baidu30a72.bf.3dtops.com                       2022-04-30     204.11.56.48
zpvpcxa.baidu.3dtops.com                               2022-04-30     204.11.56.48
zsrob.baidu.3dtops.com                                 2022-04-30     204.11.56.48
...
zycoccz.baidu.3dtops.com                               2022-04-30     204.11.56.48
...

total: 30/79882

默认条件下,用户被提供3个比较重要的字段:

1. name             域名全称
2. timestamp        建立时间戳
3. ip               ip地址

使用zoom eye domain -h 浏览域提供的参数

(base) liuxiaowei@MacBookAir ~ % python cli.py domain -h
usage: zoomeye domain [-h] [-page PAGE] [-dot] q {
   0,1}

positional arguments:
  q           search key word(eg:baidu.com)
  {
   0,1}       0: search associated domain;1: search sub domain

optional arguments:
  -h, --help  show this help message and exit
  -page PAGE  view the page of the query result
  -dot        generate a network map of the domain name

下面演示-page参数(缺省条件,page参数没有被指定)

(base) liuxiaowei@MacBookAir ~ % python cli.py domain baidu.com 0 -page 3
name                                                   timestamp      ip
zvptcfua.baidu6c7be.mm.3dtops.com                      2022-04-30     204.11.56.48
zmukxtd.baidu65c78.iw.3dtops.com                       2022-04-30     204.11.56.48
zhengwanghuangguanxianjinkaihu.baidu.fschangshi.com    2022-04-30     23.224.194.175
zibo-baidu.com                                         2022-04-30     194.56.78.148
zuwxb4.jingyan.baidu.66players.com                     2022-04-30     208.91.197.46
zhannei.baidu.com.hypestat.com                         2022-04-30     67.212.187.108
zrr.sjz-baidu.com                                      2022-04-30     204.11.56.48
zp5hd1.baidu.com.ojsdi.cn                              22022-04-30    104.149.242.155

...

zhidao.baidu.com.39883.wxeve.cn                        2022-04-30     39.98.202.39
zhizhao.baidu.com                                      2022-04-30     182.61.45.108
zfamnje.baidu.3dtops.com                               2022-04-30     204.11.56.48
zjnfza.baidu.3dtops.com                                2022-04-30     204.11.56.48

total: 90/79882

-dot参数能够生成一个域名和IP的网络地图。在使用这个函数之前,你需要安装grapvhiz。请参照grapvhiz安装指南。它支持Windows/Linux/Mac系统。-dot参数生成一个png格式的图片,同时存储原始dot语言脚本。

0x03 use SDK
1. 初始化token
1. user/pass
类似地,SDK也支持两种授权方式,username/method和APIKEY, 如下:

user/pass
from zoomeye.sdk import ZoomEye
zm = ZoomEye(username='username', password='password')

2.APIKEY

from zoomeye.sdk import ZoomEye
zm = ZoomEye(api_key="Your APIKEY")

2. SDK API
下面是SDK提供的接口和用法:

1.login()
  使用用户名/密码或者APIKEY认证
2.dork_search(dork, page=0, resource="host", facets=None)
  根据目标dork搜索指定page的数据
3.multi_page_search(dork, page=1, resource="host", facets=None)
  根据目标dork搜索多页数据
4.resources_info()
  获取当前用户信息
5.show_count()
  获取当前dork所有匹配结果的数量
6.dork_filter(keys)
  从搜索结果中提取指定字段的数据
7.get_facet()
 从搜索结果所有数据中获取统计结果
8.history_ip(ip)
  查询一个IP地址的历史数据信息
9.show_site_ip(data)
  遍历web-search结果集并输出域名和IP地址
10.show_ip_port(data)
  遍历主机搜索结果集并输出IP地址和端口
11.generate_dot(self, q, source=0, page=1)
  生成graphviz文件和图片

3. SDK 示例

(venv) (base) liuxiaowei@MacBookAir 自动运维 % python
Python 3.9.9 (v3.9.9:ccb0e6a345, Nov 15 2021, 13:29:20) 
[Clang 6.0 (clang-600.0.57)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import zoomeye.sdk as zoomeye
>>> dir(zoomeye)
['ZoomEye', 'ZoomEyeDict', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'fields_tables_host', 'fields_tables_web', 'getpass', 'graphviz', 'os', 'requests', 'show_ip_port', 'show_site_ip', 'zoomeye_api_test']


>>> # Use username and password to login
>>> zm = zoomeye.ZoomEye()
>>> zm.username='your account'
>>> zm.password='your password'
>>> print(zm.login())
.........6IkpXVCJ9.eyJpZGVudGl0eSI6IjExMzQ1OTMxNTRAc......iOjE2.......

>>> data = zm.dork_search('apache country:cn')
>>> zoomeye.show_site_ip(data)
me*****on.o****e.net.pg ['85.*.*.6
donat********63221110.b***c.net ['18.***.***.225]
soft********26216022.b***c.net ['126.***.***.22']
wat********5084068.b***c.net ['126.***.***.68']
pik********11180040.b***c.net ['106.***.***.39']

4. 搜 索
针对以上的例子,我们使用dork_search()来搜素,我们也设置facets参数获取dork全面数据的聚集统计结果,对于facets支持的字段,请参照前面的练习,操作如下:

>>> data = zm.dork_search('telnet', facets='app')
>>> zm.get_facet()
{
   'product': [{
   'name': '', 'count': 29978441}, {
   'name': 'BusyBox telnetd', 'count': 12128171}, {
   'name': 'Linux telnetd', 'count': 3502801}, {
   'name': 'MikroTik router config httpd', 'count': 2011203}, {
   'name': 'Cisco IOS telnetd', 'count': 1755109}, {
   'name': 'Huawei Home Gateway telnetd', 'count': 1452503}, {
   'name': 'Apache httpd', 'count': 1399713}, {
   'name': 'Huawei telnetd', 'count': 1139431}, {
   'name': 'Busybox telnetd', 'count': 953439}, {
   'name': 'Netgear broadband router or ZyXel VoIP adapter telnetd', 'count': 746830}]}

多页搜索(multi_page_search()),当你需要获取大量数据的时候使用这个函数,page字段指获取多少页的数据。而dork_search()只能获取指定页的数据。

5. 数据筛选
用SDK提供的dork_filter()函数,我们能够更方便的筛选数据并提取指定的数据字段,操作如下:

>>> data = zm.dork_search('telnet')
>>> zm.dork_filter('ip,port')
[['88.26.204.58', 9001], ['88.26.199.152', 9001], ['88.26.246.38', 9001], ['88.27.254.227', 9001], ['88.26.231.211', 9001], ['88.26.240.161', 9001], ['88.27.240.124', 9001], .....

由于web-search和host-search接口返回的字段是不同的,你需要填写正确的字段,web-search 包含:app/headers/keywords/title/ip/site/city/country。host-search包含:app/version/device/ip/port/hostname/city/country/asn/banner

相关文章
|
6天前
|
数据可视化 编译器 Python
Manim:数学可视化的强大工具 | python小知识
Manim(Manim Community Edition)是由3Blue1Brown的Grant Sanderson开发的数学动画引擎,专为数学和科学可视化设计。它结合了Python的灵活性与LaTeX的精确性,支持多领域的内容展示,能生成清晰、精确的数学动画,广泛应用于教育视频制作。安装简单,入门容易,适合教育工作者和编程爱好者使用。
51 7
|
21天前
|
JavaScript 前端开发 开发者
探索 DrissionPage: 强大的Python网页自动化工具
DrissionPage 是一个基于 Python 的网页自动化工具,结合了浏览器自动化的便利性和 requests 库的高效率。它提供三种页面对象:ChromiumPage、WebPage 和 SessionPage,分别适用于不同的使用场景,帮助开发者高效完成网页自动化任务。
99 4
|
23天前
|
开发者 Python
探索Python中的列表推导式:简洁而强大的工具
【10月更文挑战第41天】 在编程的世界中,效率与简洁是永恒的追求。本文将深入探讨Python编程语言中一个独特且强大的特性——列表推导式(List Comprehension)。我们将通过实际代码示例,展示如何利用这一工具简化代码、提升性能,并解决常见编程问题。无论你是初学者还是资深开发者,掌握列表推导式都将使你的Python之旅更加顺畅。
|
2月前
|
数据采集 数据可视化 数据挖掘
R语言与Python:比较两种数据分析工具
R语言和Python是目前最流行的两种数据分析工具。本文将对这两种工具进行比较,包括它们的历史、特点、应用场景、社区支持、学习资源、性能等方面,以帮助读者更好地了解和选择适合自己的数据分析工具。
39 2
|
2月前
|
C语言 开发者 Python
探索Python中的列表推导式:简洁而强大的工具
【10月更文挑战第21天】在Python的世界里,代码的优雅与效率同样重要。列表推导式(List Comprehensions)作为一种强大而简洁的工具,允许开发者通过一行代码完成对列表的复杂操作。本文将深入探讨列表推导式的使用方法、性能考量以及它如何提升代码的可读性和效率。
|
2月前
|
自然语言处理 算法 数据挖掘
探讨如何利用Python中的NLP工具,从被动收集到主动分析文本数据的过程
【10月更文挑战第11天】本文介绍了自然语言处理(NLP)在文本分析中的应用,从被动收集到主动分析的过程。通过Python代码示例,详细展示了文本预处理、特征提取、情感分析和主题建模等关键技术,帮助读者理解如何有效利用NLP工具进行文本数据分析。
52 2
|
2月前
|
测试技术 Python
Python MagicMock: Mock 变量的强大工具
Python MagicMock: Mock 变量的强大工具
51 4
|
2月前
|
存储 Python
python数据类型、debug工具(一)
python数据类型、debug工具(一)
|
1月前
|
C语言 Python
探索Python中的列表推导式:简洁而强大的工具
【10月更文挑战第24天】在Python编程的世界中,追求代码的简洁性和可读性是永恒的主题。列表推导式(List Comprehensions)作为Python语言的一个特色功能,提供了一种优雅且高效的方法来创建和处理列表。本文将深入探讨列表推导式的使用场景、语法结构以及如何通过它简化日常编程任务。
|
2月前
|
网络协议 IDE iOS开发
Python编程---简单的聊天工具
Python编程---简单的聊天工具
39 2