python测试

Python基础篇: 1 python的8种数据类型并分别列出你会的方法?

整数:int(将其他数据类型转换为整数)、to_bytes()(将整数转换为字节序列)

浮点数:float(将其他数据类型转换为浮点数)

字符串:upper()(将字符串转换为大写)、lower()(将字符串转换为小写)、split()(根据指定分隔符将字符串分割为列表)、join()(将列表中的字符串连接为一个字符串)

布尔值

列表:append()(向列表末尾添加元素)、extend()(将另一个列表的元素添加到当前列表末尾)、insert()(在指定位置插入元素)、pop()(移除并返回指定位置的元素)、remove()(移除列表中第一个匹配的元素)、index()(返回指定元素的索引)、count()(返回指定元素在列表中出现的次数)

元组:不可变、

集合:add()(向集合添加元素)、remove()

字典:keys()(返回字典中所有的键)、values()(返回字典中所有的值)

2 哪些是可变元素哪些不可变?

整数、浮点数、字符串、元组

3 为什么函数的参数不能传可变数据类型,举例说明?

传递可变数据类型,会导致函数原始的参数发生改变

def test(lst):
    lst.append(4)  # 在列表末尾添加一个新元素
my_list = [1, 2, 3]
print( my_list)  # 输出 [1, 2, 3]
​
test(my_list)
print( my_list)  # 输出 [1, 2, 3, 4]
​

4 什么是闭包?为什么使用闭包?闭包有什么优点有什么缺点?

一个函数内定义另一个函数并返回该函数,内部函数可以使用外部函数的参数

优点:可以封装变量,防止污染;可以延伸变量作用范围

缺点:占内存

5 什么是生成器迭代器和可迭代对象?

生成器:用特殊方式定义的迭代器就是生成器:1、圆括号括起来的列表生成式2、yield函数。迭代器:迭代器的概念是在可迭代对象范围以内的,调用next函数不断返回下一个值的就是迭代器。可迭代对象:可以用for循环的对象例如列表,map函数跑出来的东西

6 使用生成器生出斐波那契数列

def fib():
    a, b = 0, 1
    while True:
        yield a
        a, b = b, a + b
​
# 创建斐波那契数列的生成器
fib_1 = fib()

7使用生成器生出杨辉三角形

def yanghuisanjiao():
    row = [1]
    while True:
        yield row
        row = [1] + [row[i] + row[i+1] for i in range(len(row) - 1)] + [1]
​
# 创建杨辉三角形的生成器
yanghui = yanghuisanjiao()
​

8 什么是魔术方法,举例说明你知道的魔术方法和具体作用?

魔术方法就是双下划线开头结尾的特殊方法,实现类的特殊行为和操作,会在特殊情况下自动调用,对象的创建等例如‘init’对象的初始化方法,在创建对象的初始化方法的自动调用。

9 说说什么是类方法,静态方法,类属性,实例属性,他们有什么区别?

类方法(Class Method)和静态方法(Static Method)是类中的特殊的方法,而类属性(Class Attribute)和实例属性(Instance Attribute)是类中的特殊的属性。类属性是定义在类中,所有类的实例共享的属性;

类方法可以访问修改类属性,不能访问修改静态属性;静态方法通常不需要访问类属性或实例属性;类属性是定义在类中,类的所有的实例可以共享属性;而实例属性是定义在类的实例里面每个实例的属性可能不相等,每个实例都有自己的实例属性副本。

10 什么是单例模式?请你实现一个单例模式?

class one:
    def __init__(self, value):
        self.value = value
   
    def __new__(cls, *args, **kwargs):
        return cls._instance
    
​
# 创建单例对象
singleton1 = Singleton(10)
​
# 打印对象的值
print(singleton1.value)  # 输出 20
​
​

单例对象是指一个对象只有一个类的访问模式。

11 说说三种高级方法的使用, map reduce filter

map reduce filter 都是对列表操作的函数

map:接受一个函数和一个可迭代对象作为参数,返回一个由函数处理后的结果的可迭代对象。

reduce:函数接受一个函数和一个可迭代对象作为参数,最终返回一个值

filter:接受一个函数和一个可迭代对象作为参数,对可迭代对象中的每个元素应用函数,并返回满足函数条件的元素组成的迭代器

12 说说什么是装饰器,举个例子具体说明装饰器的作用

修饰器 本质上就是一个闭包 定义一个函数,这个函数是用来给其他函数添加额外的功能。

# 定义一个装饰器函数
def test(func):
    def wrapper():
        func()  # 调用原始函数
​
# 定义一个需要被装饰的函数
@test  # 使用装饰器装饰函数
def test1():
    print("Hello, world!")
​
# 调用装饰后的函数
test1()
​

13 说说什么是断言?有什么用?

assert(断言)用于判断一个表达式,在表达式条件为 false 的时候触发异常。断言可以在条件不满足程序运行的情况下直接返回错误,而不必等待程序运行后出现崩溃的情况,来自动检测python程序中的错误,让程序更加可靠且更易于调试

14 说如何读写文件,读文件写文件写二进制文件应该使用什么方法?

// 读文件
read123= open(file="./open.txt",mode='r',encoding='utf-8')
print(read123.read())
// 写文件
write123= open(file="./open.txt",mode='w',encoding='utf-8')
print(write123)
// 写二进制文件
write234 = open(file="./open.txt",mode='wb',encoding='utf-8')
print(write234 )

15 如何读取大文件

最常见的就用分块读取,按照固定大小的方法读取,用read就可以

16 写出冒泡排序

def Paopao(arr):
    n = len(arr)
    for i in range(n):
        for j in range(0, n-i)
            if arr[j] > arr[j+1] :
                arr[j], arr[j+1] = arr[j+1], arr[j]
 
arr = [99,44,23,58,45,12]
Paopao(arr)
for i in range(len(arr)):
    print ("%d" %arr[i]),

输出的结果是12,23,44,45,58,99

17 如何实现人工报错?

try:
  dzx = '234'
  double(dzx)
except Exception,dzx:
  print('Exception'dzx)

18 mysql 三表联查如何操作?写出伪代码?

SELECT p.pname '球员姓名',t.tname '球队名称',p.sal '薪水',p.grade '薪水等级'
FROM player 
LEFT JOIN team t
ON p.teamno=t.teamno
LEFT JOIN salgrade s
ON p.sal BETWEEN s.losal AND s.hisal;

19 如果现在已经知道有三个班级 A班 B班 C班,如何知道每个班级第二名的成绩?

假设我们数据库中有一个“student”的表,里面有学生姓名、姓名班级、成绩等字段名,要找到每个班级里面的第二名就是需要内部外部联合查询的方法来实现。

首先我们在一个班级里按照成绩降序的序列排列,并使用 ROW_NUMBER() 函数为每个学生分配排名。然后,在外部查询中,我们选择排名为第二的学生(即 rank = 2),并输出他们的班级、姓名和成绩信息。这样查询的前提是需要班级的人数大于等于2,否则出现bug。

20 说说python中的序列化反序列化以及具体作用?

序列化 :是将对象的状态信息转换为更加容易存储传输的二进制数据 反序列化:是将二进制序列转换成人能看得懂的数据

Js 基础篇: 21 如何定义一个匿名函数?(尽可能多的写出方法)

function Person(){} //Person构造函数

var p=new Person(); //Person构造函数创建对象,也可叫做实例化

22 说说js中定义变量的三种方法?他们的区别?

三种方式分别是var,let,const

区别是:

1、三种方法的作用域不同,var的作用域是函数作用域,如果变量的声明在任何函数外,那么这个变量就属于全局作用域,let和const的作用域是块级作用域,就是在在同一个块级作用域,不能重复声明变量。

2、var方法存在变量提升,另外两个不存在。(var的声明会在js预解析时把var的声明提升到当前作用域的最前面,意思是是指无论 var 出现在一个作用域的哪个位置,这个声明都属于当前的整个作用域,在其中到处都可以访问到。只有变量声明才会提升,对变量赋值并不会提升)

3、var的声明变量可以重复声明,而在同一块级作用域内,let不可以重复声明,const作为常量是不可以修改的。

23 说说构造函数,原型对象 实例对象都是什么意思?他们三个之间有什么联系?

构造函数:用来在创建对象时初始化对象。在js中任何函数都可以看做是构造函数,相当于在python中类的概念,在构造函数实例化的过程就相当于类的实例化的过程。

实例化对象:在有构造函数的前提下,可以通过new运算符一起来生成实例化对象。

原型对象:在构造函数创建的过程中,系统会自动创建出一个新的空的原型对象来匹配构造函数。

构造函数可以通过new运算符来生成实例化对象,实例化对象可以通过.proto的方式生成原型对象。

构造函数可以通过.constructor的方式来生成相对的原型对象,原型对象可以通过.prototype的方式生成构造函数。

24 说说js中一个函数的形参是否要与实参对应?如果一个函数的形参为2个,实际传递了 一个实参会发生什么情况?

在js中函数的形参不一定要与实参相互一一对应,如果形参为两个,但是在实际运用的过程中只是传了一个参数的话,那么传递的参数将会传到第一个参数中去,第二个参数将不会定义(undefined)。

25 在js中如何看待数组?数组和对象的用法是否完全一样?

在js中数组可以看做一种特殊的对象,与普通对象的功能相似,但是可以用来存储一些对象存不了的一些值,所以存储性能要比普通对象要好。

在用法上,数组主要是通过索引存取值,对象是通过键值对;在使用场景上,在面对有序的情况下用到数组,在无序的情况下主要用到对象;

26 在js中如何查看数据类型?

使用tpyeof运算符返回相对应的属性类型

27 如何设置一个对象的具体属性?比如是否可修改是否可配置是否可遍历?

使用Object.defineProperty为对象添加属性

例如Object.defineProperty(myObject,'myObject',{ value: 123, writable: false, enumerable: true, configurable: false, get: undefined, set: undefined })

28 如何将一个对象设置为另一个对象的原型对象?

通过使用Object.setPrototypeOf将一个对象设置为另一个对象的原型对象,改变原型对象的继承链

29 如何遍历一个对象上所有的属性?

使用Object.getOwnPropertyNames方法可以遍历一个对象上的所有属性包括不可遍历的

30 如果遍历一个对象上的可遍历属性?

Object.keys 方法在 Js 中用于获取一个对象自身的所有可枚举属性的键名,并以数组的形式返回。

31 如何判断一个数组中元素的个数?

可以通过.length方法来获取一个数组中的元素个数,也可以手动更改这个length的值

32 说说this相关的用法,在不同的情况下this代表了什么意思?结合代码说明?

this在js中的应用非常广泛,它的返回值总是当前属性或者方法的对象。

在构造函数中的this指的是实例对象

var Obj = function (m) {
  this.m = m;
};

上面代码定义了一个构造函数Obj。由于this指向实例对象,所以在构造函数内部定义this.m,就相当于定义实例对象有一个m`属性。

对象

如果对象的方法里面包含thisthis的指向就是方法运行时所在的对象。该方法赋值给另一个对象,就会改变this的指向。

var obj ={
  foo: function () {
    console.log(this);
  }
};

obj.foo() // obj

上面代码中,obj.foo方法执行时,它内部的this指向obj

如果this所在的方法不在对象的第一层,这时this只是指向当前一层的对象,而不会继承更上面的层。

var a = {
  p: 'Hello',
  b: {
    m: function() {
      console.log(this.p);
    }
  }
};

a.b.m() // undefined等同于 b.m() 

上面代码中,a.b.m方法在a对象的第二层,该方法内部的this不是指向a,而是指向a.b,因为实际执行的是下面的代码。

全局环境

全局环境使用this,它指的就是顶层对象window

this === window // true

function f() {
  console.log(this === window);
}
f() // true

函数的内部还是外部,只要是在全局环境下,this指的就是顶层对象`window

33 说说什么是base64?关于base64的俩个函数分别是什么?

Base64是一种表示二进制数据的编码方法,将二进制数据转换为ASCII字符串。Base64方法包含a-z,A-Z,0-9,+和/这64个字符。两个函数分别是atob()将base64转换为字符串格式,btoa()将字符串转换为base64格式。

34 说说什么是xhr断点,如何打xhr断点?

xhr断点就是在浏览器发送XHR请求时,允许暂定js代码的执行,从而获得请求的相关信息。

打xhr断点需要在浏览器界面按下F12进入开发者工具,进入source界面,找到想要打断点的js代码然后打断点就可以了

35 ‘ds23gl23s234ja’ 用什么方法可以提取出其中的数字?

用parselnt函数可以提取出来这个字符串的数字

parselnt(‘ds23gl23s234ja’ )//2323234

36 说说什么是自执行函数,一遍的表现形式是什么?

根据js的语法要求,圆括号()跟在函数名之后,表示调用该函数,有时我们在定义完函数之火,需要立刻调用函数,但是此时不能再函数的定义之后加上()。一般的写法如下;

(function(){ /* code */ }());
// 或者
(function(){ /* code */ })();

37 说说eval的作用是什么?这种东西如何对我们进行反爬,我们要如何处理?

eval 的主要作用是解析和执行传入的字符串形式的Js代码。

反爬网站可能会将重要的逻辑验证放入一个经过混淆的字符串中,并通过 eval 执行通过这种方式使得爬虫难度增加。

在面对拥有eval小网站的时候,主要方法是通过在Node.js环境下去重写eval函数去记录捕获传入eval函数的字符串内容。

38 如果一个函数没有形参,但是调用它的时候有确实传递了很多参数,那么如何接受这些参数并使用?

在函数形参没有的情况下,可以用arguments作为传参的选择,arguments是一个类似数组的对象可以包含给传递函数的所有参数,可以把传给函数的所有参数传入arguments,然后接受这些参数并使用。

39 如果一个函数返回多个值,那么实际会产生什么效果?比如下面的伪代码 Function hello(){ Return hh = 12+5,gg.t = hh,gg }

在js中一个函数的返回值只能有一个但是在面临多个返回值的情况下,可以通过数组、对象的方式来达到多个返回值的目的。

这段代码的函数返回值主要是一段表达式,‘hh = 12+5,gg.t = hh,gg’,hh是一个值即12+5为17,gg.t=hh,说明是gg的一个t属性为hh,gg是一个对象,最后这段伪代码的返回值是gg这个对象。

40 我们已知的作用域有哪些?举例说明

全局作用域,变量在整个程序中一直存在,所有地方都可以读取;

var v = 1;

function f(){
  var v = 2;
  console.log(v);
}

f() // 2
v // 1

在函数的内部和外部同时定义了v,但是在外部再去调用v的时候,全局变量的定义覆盖了局部变量的定义

函数作用域,变量只在函数内部存在。

var a = 1;
var x = function () {
  console.log(a);
};

function f() {
  var a = 2;
  x();
}

f() // 1

函数x是在函数f的外部去声明的,那么函数x的a是全局作用域定义的a不是函数f内部自定义的a。总之,函数执行时所在的作用域,是定义时的作用域,而不是调用时所在的作用域。

爬虫通用篇: 41 如果我们请求接口返回的数据是json形式但是不是标准的json,我们应该啊如何处理?

js中使用JSON.parse()

42 header头信息中有哪些常用重要的参数,分别代表什么意思?

GET:此方法用于请求指定的资源。GET请求应该安全且幂等,即多次执行相同的GET请求应该产生相同的结果。

POST:此方法用于向指定的资源提交数据,以便根据所提供的数据创建/更新资源。POST请求不是幂等的,每次执行相同的POST请求可能会产生不同的结果。

HEAD:此方法与GET方法类似,只是服务器在响应中只返回HTTP头部,而不返回实际的数据。这用于检查资源的元数据。

Host:此头部字段指定请求的主机名和/或端口号。这是必需的,因为HTTP是一个基于TCP/IP的协议,没有主机名和端口号,服务器无法知道请求来自哪里。

User-Agent:此头部字段提供了关于发送请求的应用程序或用户代理的信息。这可以包括浏览器的名称和版本、操作系统等信息。

Accept:此头部字段指定客户端接受哪些类型的数据。例如,可以指定接受HTML、JSON、XML等格式的数据。

Content-Type:此头部字段指定在POST或PUT请求中发送的数据的类型。例如,如果发送的是JSON数据,那么此头部字段应该设置为application/json。

Cookie:此头部字段包含由服务器发送的cookie信息,这些信息将在后续的请求中自动包含,以便服务器识别用户或保存状态信息。

43什么是线程进程协成?它们之间有什么区别?你更提倡用哪种?

进程:是系统进行资源分配和调度的基本单位,是操作系统结构的基础

线程:是程序执行中一个单一的顺序控制流程,是程序执行流的最小单元,是处理器调度和分派的基本单位

协程:是一种比线程更加轻量级的存在。正如一个进程可以拥有多个线程一样,一个线程也可以拥有多个协程;完全是由程序所控制

区别:进程拥有自己的资源空间,一个进程包含若干个线程,线程与CPU资源分配无关,多个线程共享同一进程内的资源

我的建议是协程,轻量级的开发存在

44 我们抓取网页数据的步骤是什么(比如,源码没有数据怎么查看,如果还是没有有哪些可能性,怎么处理呢)

查看数据是不是在接口上,如果在接口上单纯的访问接口url,如果没有在接口上的话,就是要看是不是Ajex存在

45 如何不考虑追溯源码,如何判断一段加密代码到底是什么加密?

1、md5加密:产生出一个128位(16字节)的散列值

2、Base64加密:只有64个字符(英文大小写、数字和+、/)以及用作后缀等号

3、ASCII编码:密文是十进制,字符范围是“0-9”

46画出scrapy 框架的流程图并写出运行流程?

image-20240516190615446

(1)首先 先从Spider发送一个请求,初始化了一个Resquest对象,并且设置了回调函数(也就是创建Scrapy项目后的def parse(self, response)),把请求传给引擎。

(2)引擎收到请求后,并不会把请求马上发送出去,而是传给了调度器。调度器接受到引擎发过来的Requser请求后,把Request对象按照一定的排序算法存储到它里面的一个队列当中。

(3) 接下来引擎会不断的从调度器当中取出已经处理好的Request

(4) 当引擎拿到Request后,再把这个请求扔给下载器。

(5)下载器拿到请求后,按照下载中间件中的设置去互联网上面下载request请求。下载好数据后再把数据传送给引擎。

(6)引擎拿到数据之后,再把这个数据(也就是response)通过爬虫中间件返回给Spider。并把response作为参数传递给第一步设置好的回调函数。

(7)爬虫拿到数据之后(这个爬虫是由我们自己写),经过分析,把不需要的数据剔除掉,把需要的数据提取出来(使用xpath、BeautifulSoup、正则)。接下来再把提取出来的数据扔给引擎。

(8) 引擎拿到数据之后,把这个数据扔给实体管道(如果这时还有其他的Requset,会重复3-8这个过程,直到获取完所有的自己想要的信息)。

47 说说scrapy downloadmiddleware中包含哪些方法,都起到什么作用?

process_request(request, spider):

Request被Scrapy引擎调度给Downloader之前,process_request()方法就会被调用,也就是在Request从队列里调度出来到Downloader下载执行之前,我们都可以用process_request()方法对Request进行处理。方法的返回值必须为None、Response对象、Request对象之一,或者抛出IgnoreRequest异常。

process_request()方法的参数有如下两个:

request,是Request对象,即被处理的Request。

spider,是Spdier对象,即此Request对应的Spider。


process_response(request, response, spider):

Downloader执行Request下载之后,会得到对应的Response。Scrapy引擎便会将Response发送给Spider进行解析。在发送之前,我们都可以用process_response()方法来对Response进行处理。方法的返回值必须为Request对象、Response对象之一,或者抛出IgnoreRequest异常。

process_response()方法的参数有如下三个:

request,是Request对象,即此Response对应的Request。

response,是Response对象,即此被处理的Response。

spider,是Spider对象,即此Response对应的Spider


process_excepti on(request, excepti on, spider) :

当Downloader或process_request()方法抛出异常时,例如抛出IgnoreRequest异常,process_exception()方法就会被调用。方法的返回值必须为None、Response对象、Request对象之一。

process_exception()方法的参数有如下三个:

request,是Request对象,即产生异常的Request。

exception,是Exception对象,即抛出的异常。

spdier,是Spider对象,即Request对应的Spider


48 说说scrapy框架的去重机制是怎么样的?

Scarpy有自动去重功能,使用了python集合,集合记录了request的指纹,将request内容进行加密计算得到request散列,将散列值映射到集合中。

49 说说什么是布隆过滤器,大体的实现思路是什么?有什么优缺点?

Bloom Filter 使用位数组表示一个待检测集合,并可以快速地通过概率算法判断一个元素是否存在于这个集合中。利用这个算法我们可以实现去重效果

优点:不需要存储key,节省空间 缺点:只能存

50 说说什么是字体加密,遇到字体加密的大体处理思路是什么?

字体加密:通过 CSS 字体库的方式,使得页面源码中的数据与显示出来的数据不同的一种加密方式。

处理思路:

先找到字体文件的位置,查看源码大概就是xxx.tff/eot/ woff这样的文件

重复上面那个操作,将两个字体文件保存下来

用上面的软件或者网址打开,并且通过 Python fontTools 将 tff 文件解析为 xml 文件

根据字体文件解析出来的 xml 文件与类似上面的字体界面找出相同内容的映射规律

51 说说scrapy_redis是什么东西,有什么作用?

是基于redis组件的爬虫 作用:防止一个网站中同样的内容被重复爬取

52 简单说说如果一个接口存在无法解决的加密,我们应该如何进行处理?

在模拟虚拟环境下,通过逆向分析加密算法尝试解密;若是接口的返回数据被加密的情况下可以通过模拟请求的方法来解密

53 如果在nodejs环境中使用MD5加密对一个数据加密?举例说明

const dzx = require('dzx');

// 要加密的数据
const data = 'Hello, world!';

// 创建 MD5 加密器
const md5 = dzx.createHash('md5');

// 更新加密器的数据
md5.update(data);

// 计算并获取加密后的结果
const encryptedData = md5.digest('hex');

console.log('加密后的数据(MD5):', encryptedData);

54 nodejs 环境中是否有window ,如果没有它的公共变量是什么?

没有,global

55 什么是ob混淆,如何能够判断一段代码是否进行过ob混淆,它有什么具体特征?

ob混淆就是:将js代码变得难以理解,变、函数、自执行函数,无具体特征

56 如果要实现带验证码的模拟登录,有哪些方法思路?

第三方识别平台,如超级鹰等

57 说说代理IP池实现 的思路,分成哪几个部分,每个部分主要负责实现什么功能,整个架构如何运行的。

代理IP池的设计严谨分为4个模块,其中一个模块是操作redis数据库的模块并不主要讲,主要关注的点在于其他三个模块:获取模块(生产者)、检测模块:检测模块的主要作用是筛选报废的IP;调用模块(消费者):调用接口

获取模块(生产者):古早的方式是从各个免费的代理IP网站获取代理IP,就是在代理网站上面做爬虫,爬的内容就是各个代理IP,将爬下来的代理IP存入到redis数据库中,存储的方式是有序集合。

#有序集合是redis数据库中的一种数据形式,特征是集合的特征:1、可以自动去重 2、自动排序把序作为分数(序是可以重复的,也就是说可以两个序都是一样的值)同时它也是中心模块 和基础模块,将其他模块串联起来。pyquery要去学会;父类子类继承,子类就是抓取网站的规则path(每个网站的抓取规则是不一样的),父类就是basegrouper还有就是抓取网站的方法,fash方法。装饰器的作用就是重试,里面有相关的重试参数(重试次数,重试间隔等)。

动态插件方法:把子类看作一个插件可以用。本质上来说就是通过插件一次性读取子类所有的类,进行实例化,然后调用run方法,使子类和父类联合作用,然后使要抓的代理IP入库。好处就是不需要修改原来的代码,只需要去添加新的子类就可以去爬新的网站。这种古早的这么模式下的代理IP的获取方法已经被废除,代理性能差,速度慢还有安全性的问题。直接从代理网站上请求接口直接往代码里面插就可以了。

检测模块:检测代理IP是不是IP,有网段检测和端口号是不是数字检测。协程的作用就是为了快一点,检测模块的主要任务就是读取数据库中的内容,20个一组去读。检测模块的主要检测方法:分别将代理IP加上的前后去检测IP的网站判断IP是否加上,另外一种是判断加上的代理IP是不是请求的代理IP,如果成功的话,在百度上面测试一下看看这个状态码是不是200、300。如果是通用爬虫的话就是百度,如果不是通用爬虫的话就是要去自己爬虫的网站去试一下。检测模块可以删除IP,调用模块不可以删除,只读。

端口模块(消费者):flask框架开接口,调用接口,避免访问数据库,提高安全性。

58 选择代理IP的标准有哪些?

请求速度,安全,代理IP数,允许的请求间隔,价格,具体使用场景等

59 如何用ddddocr 识别一段汉字,举例说明

import ddddocr
import cv2

img1 = cv2.imread('img1.jpg')
height = len(img1)
width = len(img1[0])
img2 = img1[0:min(width,height),0:min(width,height)]
cv2.imwrite('img2.jpg',img2)

det = ddddocr.DdddOcr(det=True,show_ad=False)
with open('img2.jpg', 'rb') as f:
    img2_bytes = f.read()
poses = det.detection(img2_bytes)
img2 = cv2.imread('img2.jpg')

for box in poses:
    x1, y1, x2, y2 = box
    img2 = cv2.rectangle(img2, (x1, y1), (x2, y2), color=(0,0,255), thickness=2)

cv2.imwrite('result.jpg',img2)

60 如果一个网站是瀑布流的形式,没有最大页数,那么我们翻到超过最大页之后有哪些可能性?如何处理?

网页跳转或着404,用自己给传参的方式处理。

  • 6
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小董和你拼了!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值