首页 > 系统相关 >超能组合:python 的开发效率 + go 的并发 + shell 的短小精悍

超能组合:python 的开发效率 + go 的并发 + shell 的短小精悍

时间:2023-10-06 14:11:22浏览次数:35  
标签:shell divide python number separator file go path

工具思维:利用合适的工具做合适的事情,然后合理地加以组合。

在”谈谈程序员应当具备的技术思维“一文中谈到了工具思维。本文对工具思维作一发挥运用。

批量下载图片

程序员总是有点”美图“爱好的。由于程序员通常又是比较”懒惰“的(可没有那个耐心和体力去一页页点开再点击按钮),那么,就会想到用程序来自动化拉取美图啦。

“写了一个下载图片和视频的python小工具” 一文中,给出了一个下载图片和视频的 python 程序。

譬如,使用如下命令:

python3 dw.py -u https://dp.pconline.com.cn/list/all_t601.html -c picLink -t img -s "#J-BigPic img"

可以下载 https://dp.pconline.com.cn/list/all_t601.html 这个页面的每一个入口点进去的第一个图片(经测试,这个程序还有点不太稳定,主要是拉取网页内容不太稳定)。

假设有多个这样的页面呢?比如也要下载 https://dp.pconline.com.cn/list/all_t204.html 里的图片?

我们可以把这些命令放在一个文件 cmds.sh 里

python3 dw.py -u https://dp.pconline.com.cn/list/all_t601.html -c picLink -t img -s "#J-BigPic img"
python3 dw.py -u https://dp.pconline.com.cn/list/all_t204.html -c picLink -t img -s "#J-BigPic img"

然后:

chmod +w cmds.sh
./cmds.sh

这样可以依次执行这两个命令。

不过这样只能利用单核,难以利用多核的优势(目前主流电脑的配置都是多核的)。好在,我们可以使用 Go 的并发进行组合。

并发批量下载图片

再写一个 Go 的程序,这个程序能够从指定文件里读取命令,并发执行这些命令:

go run multi_run.go -f cmds.sh 

multi_run.go

package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"os/exec"
	"strings"
	"sync"
)

var wg sync.WaitGroup

func RunCmd(cmdstr string) {

	defer wg.Done()
	cmd := exec.Command("/bin/bash", "-c", cmdstr)

	output, err := cmd.CombinedOutput()
	if err != nil {
		fmt.Printf("Exec cmd failed. error: %s, output: %s", err.Error(), string(output))
		return
	}
	fmt.Printf("Exec cmd finished. %s", string(output))
}

func parse() *string {
	filePtr := flag.String("f", "", "cmd文件")

	// 解析命令行参数
	flag.Parse()

	return filePtr
}

func Read(filename string) string {
	f, err := ioutil.ReadFile(filename)
	if err != nil {
		fmt.Println("read fail", err)
	}
	return string(f)
}

func main() {

	filePtr := parse()

	filecontent := Read(*filePtr)
	lines := strings.Split(filecontent, "\n")
	lens := len(lines)

	for i := 0; i < lens; i++ {
		line := lines[i]
		if len(line) != 0 {
			wg.Add(1)
			go RunCmd(line)
		}
	}

	wg.Wait()

}

如果这样的命令很多,可以切割为多个文件:

python3 divide.py -f cmds.sh -n 2 -s '-'

divide.py

#!/usr/bin/python
#_*_encoding:utf-8_*_

import sys
import os
import argparse
import traceback
import math


def usage():

    usage_info = '''
        This program is used to divide lines of specified file into specified numbers of file.

        options:
              -f --file file need to divide 
              -n --number divide into N files
        eg.
             python3 divide.py -f cmds.txt -n 5 -s '-'
             python3 divide.py -f cmds.txt -n 5

    '''

    print(usage_info)


def parseArgs():
    try:
        description = '''This program is used to batch download pictures or videos from specified urls.
                                will search and download pictures or videos from network url by specified rules.
                      '''
        parser = argparse.ArgumentParser(description=description)
        parser.add_argument('-f','--file', help='file need to divide', required=True)
        parser.add_argument('-n','--number', help='divide into N', required=False)
        parser.add_argument('-s', '--separator', help='separator specified', required=False)
        args = parser.parse_args()
        print(args)
        file = args.file
        number = int(args.number)
        separator = args.separator
        print("%s %s %s" % (file, number, separator))
        return (file, number, separator)
    except:
        usage()
        traceback.print_exc()
        exit(1)


def divideNParts(total, N):
    '''
       divide [0, total) into N parts:
        return [(0, total/N), (total/N, 2M/N), ((N-1)*total/N, total)]
    '''

    each = math.floor(total / N)
    parts = []
    for index in range(N):
        begin = index*each
        if index == N-1:
            end = total
        else:
            end = begin + each
        parts.append((begin, end))
    print('divided into: %s' % str(parts))
    return parts

def get_file_name(file_path):
    file_name = os.path.basename(file_path)
    file_name_without_extension = os.path.splitext(file_name)[0]
    return file_name_without_extension

def get_file_ext(file_path):
    return os.path.splitext(file_path)[1]

if '__main__' == __name__:

    (file_path, number, separator) = parseArgs()
    print("file_path: %s number:%s separator: %s" %(file_path, number, separator))

    if not number:
        number = 10
    if not separator:
        separator = '_'

    lines = open(file_path)

    all_lines = []
    for line in lines:
        all_lines.append(line.strip())

    nparts = divideNParts(len(all_lines), number)

    count = 0
    file_prefix = get_file_name(file_path)
    for part in nparts:
        parts = all_lines[part[0]:part[1]]
        with open(file_prefix + separator + str(count)+ get_file_ext(file_path),"w") as fo:
            for o in parts:
                fo.write(o)
                fo.write('\n')
        count += 1

循环一下:

for i in {0..1} ; do go run multi_go.run -f cmds-${i}.sh ; done

这样,我们就把 python, shell, go 三者的优势组合起来了:

  • python: 语法简洁、开发效率高、库丰富;
  • go: 利用多核并发
  • shell: 短小精悍、连接多个程序组成完整功能。

这就是学习多语言的益处:可以充分组合多种语言各自的优势,来更好滴完成任务。

避免 Chrome 自动更新的最新方法

由于 dw.py 使用了 chromedriver ,chromedriver 的版本需要与 chrome 的版本保持一致。而 chrome 会时常更新,而 chromedriver 不会时常更新,因此需要禁用 chrome 更新。

在 Mac chrome 114 版本上,最新的方法如下(其它方式试过不可行了):

在终端:

cd /Library/Google/
sudo chown nobody:nogroup GoogleSoftwareUpdate
sudo chmod 000 GoogleSoftwareUpdate
cd ~/Library/Google/
sudo chown nobody:nogroup GoogleSoftwareUpdate
sudo chmod 000 GoogleSoftwareUpdate

然后对文件夹 Google 上一级执行相同的操作。

cd /Library/
sudo chown nobody:nogroup Google
sudo chmod 000 Google
cd ~/Library/
sudo chown nobody:nogroup Google
sudo chmod 000 Google


标签:shell,divide,python,number,separator,file,go,path
From: https://www.cnblogs.com/lovesqcc/p/17744524.html

相关文章

  • 不同宽度,厚度,重量,车间温度下,物料温度随时间而衰减的曲线不同,请使用python机器学
    要使用Python机器学习拟合物料温度随时间衰减的曲线,你可以遵循以下步骤:收集数据:首先,你需要收集不同宽度、厚度、重量和车间温度下的物料温度随时间的数据。确保数据集包含了足够的样本,以便于训练和测试机器学习模型。数据预处理:对数据进行预处理,包括数据清洗、缺失值处理和特征工程......
  • Go - Parsing Time Displays Into Structs
     funcmain(){str:="4:31am+0800onOct1,2021"layout:="3:04pm-0700onJan2,2006"t,err:=time.Parse(layout,str)iferr!=nil{log.Println("C......
  • Go - Formatting time
     funcmain(){t:=time.Now()fmt.Println(t.Format("3:04PM"))fmt.Println(t.Format("Jan02,2006"))}Whenyourunthisyoushouldseesomethinglike:1:45PMOct23,2021That’ssimpl......
  • Go - Measuring Lapsed Time
    Problem: Youwanttomeasurethelapsedtimeandmakesurethatitisaccurate.Solution: UsethemonotonicclockintheTimestructtofindthelapsedtime. TheTimestructcontainsthedatabutonlyundercertaincircumstances.IfyoucreateaTimes......
  • Python爬虫源码,Behance 作品图片及内容采集爬虫附工具脚本!
    Behance网站是设计师灵感必备网站这个网站跟国内的网站,花瓣网很像,甚至可以说花瓣学习了它不少,在瀑布流网页的展示上也有很多相似之处。前面本渣渣就分享过花瓣网图片采集爬虫,感兴趣可以移步查看,现在还能用!【爬虫】花瓣图片爬虫,Python图片采集下载源码Python爬虫tkinter,花瓣工业设......
  • go通过pprof定位groutine泄漏
    日常开发中除了会出现Panic、ErrorInfo等通过日志很容易捕捉到的错误,还会出现内存泄漏、CPU激增等日志难以捕捉的问题。今天小老虎就给大家介绍下如何使用pprof去捕捉内存、CPU这些日志难以排查到的问题。pprof的访问pprof是Golang的性能分析工具,可以帮助我们查看程序在运行过程中C......
  • 了解python闭包
    了解python闭包1、闭包的作用当函数调用结束之后,函数内定义的变量都销毁了,但是有时候我们需要函数内的这个变量,每次在这个变量的基础上完成一系列的操作。(即在调用完函数之后,仍然想使用函数内部的变量)那么我们可以使用闭包来解决这个需求。闭包的定义:在函数嵌套的前提下,内部......
  • 基于python的食力派网上订餐系统-计算机毕业设计源码+LW文档
    摘 要在各学校的教学过程中,食力派网上订餐系统是一项非常重要的事情。随着计算机多媒体技术的发展和网络的普及。采用当前流行的B/S模式以及3层架构的设计思想通过Python技术来开发此系统的目的是建立一个配合网络环境的食力派网上订餐系统,这样可以有效地解决食力派网上订餐管理......
  • 【python自动化】七月PytestAutoApi开源框架学习笔记(二)
    执行流程注:请先阅读作者的README.md文档https://gitee.com/yu_xiao_qi/pytest-auto-api2/blob/master/README.md本节内容目录如下:文章目录执行流程目录结构参数配置入口文件-run.pypytest.initest_case初始化数据缓存解析yaml测试数据测试用例执行conftest.py用例demo分析加载yaml......
  • 【AI测试】python文字图像识别tesseract
    [AI测试]python文字图像识别tesseractgithub官网:https://github.com/tesseract-ocr/tesseractpython版本:https://github.com/madmaze/pytesseractOCR,即OpticalCharacterRecognition,光学字符识别,是指通过扫描字符,然后通过其形状将其翻译成电子文本的过程。对于图形验证码来说,它们......