最近遇到和看到的python爬虫实习岗的面试基础题

最近遇到和看到的python爬虫实习岗的面试基础题----以后遇到其他会补充

continue 语句
continue跳出本次循环,而break跳出整个循环。
continue用来告诉Python跳过当前循环的剩余语句,然后继续进行下一轮循环。

python优点
1、开发效率非常高,Python有非常强大的第三方库
2、高级语言————当你用Python语言编写程序的时候,你无需考虑诸如如何管理你的程序使用的内存一类的底层细节
3、可移植性————由于它的开源本质,Python已经被移植在许多平台上(经过改动使它能够工 作在不同平台上)。
4、可扩展性————如果你需要你的一段关键代码运行得更快或者希望某些算法不公开,你可以把你的部分程序用C或C++编写,然后在你的Python程序中使用它们。
5、可嵌入性————你可以把Python嵌入你的C/C++程序,从而向你的程序用户提供脚本功能。

python缺点
1、速度慢于c与java
2、代码不能加密,因为PYTHON是解释性语言,它的源码都是以名文形式存放的
3、线程不能利用多CPU问题,GIL即全局解释器锁,是计算机程序设计语言解释器用于同步线程的工具,使得任何时刻仅有一个线程在执行,
Python的线程是操作系统的原生线程。在Linux上为pthread,在Windows上为Win thread,完全由操作系统调度线程的执行。
一个python解释器进程内有一条主线程,以及多条用户程序的执行线程。即使在多核CPU平台上,由于GIL的存在,所以禁止多线程的并行执行。

python中有可变对象和不可变对象,可变对象:list,dict.不可变对象有:int,string,float,tuple。

元组用( ),应用场景:1.函数的参数和返回值,一个函数可以接收任意多个参数,一次返回多个数据
2.格式字符串
3.让列表不可以被修改,保护数据。
特点:1、元组是静态的,是固定且不可改变的,它的内容无法被修改或它的大小也无法被改变,若想要修改,可以通过拷贝现有的元组片段构造一个新的元组的方式解决。
通过分片的方法让元组拆分成两部分,然后再使用连接操作符(+)合并成一个新元组,最后将原来的变量名(temp)指向连接好的新元组。
2、元组是静态的,速度快于列表

列表用[ ],特点: 1、列表是动态数组,它们可变且可以重设长度(改变其内部元素的个数)
2、有序的集合
3、通过偏移来索引,从而读取数据
4、支持嵌套

字典用{ }特点: 1、字典是通过键值对的方式就数据存储下来,键必须是唯一的
// 字典
定义:可变的无序的
键:使用不可变数据类型(可哈希),键是唯一的
值:可以任意
#增
dic = {“k1”:“v1”,“k2”:“v2”,“k3”:“v3”}
dic[“k4”] = “v4” # 暴力添加
dic.setdefault[“k4”,“v4”] # 如果字典中k4存在值,则不添加

#删
del dic[“k4”] # 删除键为k4的键值
dic.clear() # 清空字典
dic.pop(“k4”) # 删除k4的键值,没有默认删除

#改
dic[“k2”] = “v22”
dic.update() # dic.update(dic1) 将dic1所有的键值输出到dic字典中

#查
dic[“键”] # dic[“k2”] 存在返回字典中键对应的值,不存在报错
dic.get(“键”) # dic[“k2”] 获取k2的值 存在返回字典中对应的值,不存在返回None

#合并字典
dic1.update(dic2)

集合s = set([ ]/( )/" ")特点:1、重复的值在集合中只存在一个。

如何在一个FUNCTION里面设置一个全局变量
变量前加global就ok了

这两个参数是什么意思?args和 kwargs。
args和kwargs这两个都是不定长参数,可以解决函数中参数不固定的问题,*args可以把位置参数转化成元组,kwagrs可以把关键字参数转化成字段
*args和
kwargs都是用于函数中传递参数的,args传递的是非键值对的参数,**kwargs传递的是带键值对的参数
往函数中以列表和元组的形式传参数时,那就使要用
args
传入字典的值作为关键词参数时,那就要使用
kwargs
传入元组和列表,使用
args
*args返回元组
kwargs返回字典
如果你想要在一个函数里处理带名字的参数, 你应该使用
kwargs。

python中有可变对象和不可变对象,可变对象:list,dict.不可变对象有:int,string,float,tuple。
赋值、浅拷贝、深拷贝区别
1、赋值:简单地拷贝对象的引用,两个对象的id相同。
2、浅拷贝:创建一个新的组合对象,对象的元素被复制,但子对象依旧是引用。
示例:
a=[1,2,[‘str1’,‘str2’]]
from copy import copy
b=copy(a)
a.append(3)
print(b)
print(a)
结果
[1, 2, [‘str1’, ‘str2’]]
[1, 2, [‘str1’, ‘str2’], 3]
3、深拷贝:创建一个新的组合对象,同时递归地拷贝所有子对象,新的组合对象与原对象没有任何关联。
虽然实际上会共享不可变的子对象,但不影响它们的相互独立性。

请写出一段python代码实现删除list中的重复元素。
两种方法:
(1)利用字典的fromkeys来自动过滤重复值
(2)利用集合set的特性,元素是非重复的

方法一:
a = [1, 2, 3, 4, 5, 2, 3]
def fun1(a):
b = {}
b = b.fromkeys(a)
c = list(b.keys())
print©
c = fun1(a)
方法二:
a = [1, 2, 3, 4, 5, 2, 3]
def fun1(a):
a = list(set(a))
print(a)
fun1(a)

统计如下list单词及其出现的次数。
a=[‘apple’, ‘banana’, ‘apple’, ‘tomato’, ‘orange’, ‘apple’, ‘banana’, ‘watermeton’]

利用python的collections包。
from collections import Counter
a = [‘apple’, ‘banana’, ‘apple’, ‘tomato’, ‘orange’, ‘apple’, ‘banana’, ‘watermeton’]
d = Counter(a)
print(d)

给列表中的字典排序:例如有如下list对象:
alist=[{“name”:“a”, “age”:20}, {“name”:“b”, “age”:30}, {“name”:“c”, “age”:25}] 将alist中的元素按照age从小到大排序。
利用list的内建函数,list.sort()来进行排序。
alist = [{“name”: “a”, “age”: 20}, {“name”: “b”, “age”: 30}, {“name”: “c”, “age”: 25}]
alist.sort(key=lambda x: x[‘age’])
print(alist)

数据加密方式
1、对称密钥加密----形式:客户端首先制定一种加密方式,对要发送的数据加密,将密钥与加密后的数据发送到服务器端,服务器使用密钥解密加密的数据
弊端:当密文与密钥同时被第三方拦截,密文将被破解
2、非对称密钥加密----形式:服务器端设定密钥对,将公钥发送给客户端,客户端使用密钥加密数据,再将密文发送给服务器端,服务器使用私钥解密密文(传输过程中只有公钥)
弊端:1、效率比较低 2、公钥可能被拦截篡改
3、证书密钥加密----形式:服务器设定加密方式,将公钥递交到证书认证机构,证书认证机构审核公钥,通过后机构对公钥进行数字签名并将公钥封装到证书当中,将证书发送到客户端,客户端使用其中的公钥加密数据,发送密文到服务器端

http和https的区别?

A. http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。
B. http适合于对传输速度、安全性要求不是很高,且需要快速开发的应用。如web应用,小的手机游戏等等。而https适用于任何场景。

http协议(超文本传输协议):服务器与客户端进行数据交互的一种形式。需要遵从该协议,两者才能通过该协议进行数据交互。http协议无加密
https协议:安全的http协议,安全实现—加密数据。加密方式---- 证书密钥加密

常用请求头信息
user-agent-------user-agent是请求载体的身份标识
浏览器的身份标识是统一的,但爬虫程序的身份标识是各自不同的
connection-------请求完成后,是断开连接还是保持连接

常用响应头信息
content-type:服务器响应会客户端的数据类型

动态加载数据
我们通过request模块爬取数据无法每次都能实现先可见即可得
有些数据是通过非浏览器地址栏中的url请求到的数据,俄式其他请求到的数据,那么这些通过其他请求请求到的数据就是动态加载的数据

反爬虫的手段
(1)通过User-Agent校验反爬
浏览器在发送请求的时候,会附带一部分浏览器及当前系统环境的参数给服务器,服务器会通过User-Agent的值来区分不同的浏览器。
解决方法:加headers

(2)通过访问频度反爬
普通用户通过浏览器访问网站的速度相对爬虫而言要慢的多,所以不少网站会利用这一点对访问频度设定一个阈值,
如果一个IP单位时间内访问频度超过了预设的阈值,将会对该IP做出访问限制。
解决方法:设置一个代理ip池,每次爬取都从ip池中随机拿取一个ip

(3 ) 通过验证码校验反爬
有部分网站不论访问频度如何,一定要来访者输入验证码才能继续操作。
例如12306网站,不管是登陆还是购票,全部需要验证验证码,与访问频度无关。
解决方法:使用Python的第三方库,tesserocr。对于没有什么背影影响的验证码,直接通过这个库来识别就可以。
但是对于有嘈杂的背景的验证码这种,直接识别识别率会很低,遇到这种就得需要先处理一下图片,先对图片进行灰度化,然后再进行二值化,再去识别,这样识别率会大大提高。

(4) 通过变换网页结构反爬
一些社交网站常常会更换网页结构,而爬虫大部分情况下都需要通过网页结构来解析需要的数据,
所以这种做法也能起到反爬虫的作用。在网页结构变换后,爬虫往往无法在原本的网页位置找到原本需要的内容。

(5)对数据进行加密处理

(6)设置登录访问权限

数据结构之堆,栈和队列的理解和实现。
队列(queue):
队列是一种特殊的线性表,特殊之处在于它只允许在表的队头进行删除操作,而在表的队尾进行插入操作,
栈(stack):
栈(stack)又名堆栈,它是一种运算受限的线性表。其限制是仅允许在表的一端进行插入和删除运算。
这一端被称为栈顶,相对地,把另一端称为栈底,栈就相当于一个有底的水桶,出栈的过程就像倒出水的过程,是先进后出。
堆(Heap):
堆是动态分配内存,对其访问和对一般内存的访问没有区别。
堆是指程序运行时申请的动态内存,对于堆,我们可以随心所欲的进行增加变量和删除变量。

如何查找到二叉树两个节点的最低公共祖节点
先遍历二叉树,找到从根到两个节点的两条路径,然后再求解出两条路径的第一个公共交点,为最低共同祖先。

简述面向对象中__new__和__init__区别
先执行__new__,再执行__init__
__new__是在实例创建之前被调用的,因为它的任务就是创建实例然后返回该实例对象,是个静态方法。
__init__是当实例对象创建完成后被调用的,然后设置对象属性的一些初始值,通常用在初始化一个类实例的时候。是一个实例方法。
也就是: __new__先被调用,__init__后被调用,__new__的返回值(实例)将传递给__init__方法的第一个参数,然后__init__给这个实例设置一些参数
new至少要有一个参数cls,new必须要有返回值
init有一个self参数,不需要返回值

with方法做了什么
with方法帮我们实现了finally中f.close(关闭文件)

map函数用法
list=[1,2,3,4,5]
def fn(x)
return x**2
res=map(fn,list)

避免转义给字符串加哪个字母表示原始字符串
r , 表示需要原始字符串,不转义特殊字符。

正则表达式提取标签中内容
str=‘

中国

res=re.findall(r’
(. ?)
’,str)
re.findall(r’<标签名 class=".">(.*?)</标签名>’,字符串)

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值