爬虫学习笔记

41 阅读9分钟

pip的使用

使用pip管理Python包

pip install <包名> 安装指定的包

pip uninstall <包名> 删除指定的包

pip list 显示已经安装的包

pip freeze 显示已经安装的包,并且以指定的格式显示

修改pip下载源

pip install 包名 -i 国内源地址

Python基础

数据类型

1、Number数字

int  有符号整形
float  浮点型
complex  复数

2、 布尔

True
Flase

3、String字符串

4、 List列表

5、 Tuple元组

6、Dictionary字典

查看数据类型

1、变量没有类型,数据才有类型。

a = "abc"  // 字符串
a = 123  // int
b  // 无法确定b的类型,因为b没有值

2、查看变量存储的数据类型 type()

a = "123"
type(a)  // str

标识符和关键字

1、标识符由字母、下划线和数字组成,且数字不能开头

2、严格区分大小写

3、不能使用关键字

4、命名规则

小驼峰命名法:第一个单词以小写字母开始,第二个单子的首字母大写
大驼峰命名法:每一个单词的首字母都采用大写字母

类型转换

1、转换为整数

int(x)
// 将float转换成整数只会截取小数点之前的数,例如 1.23 -> 1; 1.68 -> 1
// '1.23' -> int  无法执行,因为字符串中包含非法字符小数点

2、转换为浮点数

float(x)

3、转换为字符串

str(x)

4、转换为布尔值

bool(x)
// 整数大于0True,小于0False
// 浮点数不为0的都为True,-1.0也为True0False0.0也为False

运算符

1、在Python中,只有两端都是字符串的时候才可以进行字符串的拼接,例如:"123"+456会报错

2、字符串的乘法表示字符串重复多少次

3、赋值可以进行多个变量赋值

a = b = 4
print(a)  // 4
print(b)  // 4

4、多个变量赋值(使用逗号分隔)

num1,num2,num3 = 1,1.2,"123"
print(num1)  // 1
print(num2)  // 1.2
print(num3)  // 123 (字符串)

5、and和or都有性能优化,前面执行能出结果的,后面的语句就不执行了

格式化输出

%s:字符串
%d:数值

字符串的操作

len()  // 获取长度,例如:len(s1)
find()  // 查找内容,返回查找内容在目标字符串中第一次出现的位置,例如:s1.find("c")
startswith()  // 字符串是否以该字符串开头,正确返回true,否则返回false,例如:s1.startswith("c")
endswith()  // 字符串是否以该字符串结尾,同以上
count()  // 返回区间段中查找内容出现的次数,例如:s1.count("c",0,3)
replace()  // 替换字符串中指定内容,如果指定count,则替换次数不会超过count次  例如:把c都换成d,s1.replace("c","d",2)
split()  // 切割,返回列表,例如:s1.split('#')
upper()  // 将每个字母转成大写
lower()  // 将每个字母转成小写
strip()  // 去空格
join()  // 拼接,在每个字母后面都加,例如:s1="9";s1.join("hello") -> h9e9l9l9o9

列表的操作

新增

append()  // 追加,在列表的最后添加一个对象/数据
insert(index,str)  // 在索引为index的地方插入str
extend(a)  // 可以将另一个列表的元素逐一添加到列表中,其中a一定得是可迭代数据,
例如:a=["a","b"];b=["d","e"]; a.extend(b) -> a:["a","b","d","e"];b:["d","e"]  总之是会更改a本身的值 

修改

直接通过下标索引修改:s1[2] = "hello"

查询

in  // 判断某个是否在列表中,例如:if food in food_list:
not in  // 判断某个是否不在列表中,例如:if food not in food_list:

删除

del  // 根据下标进行删除,直接对原数据进行更改,
例如:a=[1,2,3]; del a[2]; a -> [1,2]
pop()  // 删除列表中最后一个元素,直接对原数据进行更改,
例如:b=[4,5,6]; b.pop(); b -> [4,5]
remove()  // 根据元素的值进行删除
例如:c=[1,2,3,4,5,6]; c.remove(3); c -> [1,2,4,5,6]

元组与列表的区别

1、元组与列表的区别:元组不可修改

2、当元组只有一个元素的时候,末尾要加逗号,不然的话就会是整型

例如:a_tuple = (1,)

切片

1、字符串、列表、元组都支持切片

2、遵循左闭右开的原则

字典的操作

查询

1、使用[]的方式获取不存在的key:报错

2、不可使用点的方式访问字典的数据

3、get()方法

person = {'name':'张三','sex':'男'}
person.get("name")  // 张三
person.get("age")  // None  注意获取没有的key的时候返回None,非报错

修改

person['name'] = '李四'

添加

person['age'] = 18

删除

del  // 删除字典中指定的某一个元素;删除整个字典
例如:del person['age']; del person
clear()  // 清空字典里的内容,最后保留一个空字典
例如:person.clear()

遍历

遍历字典的key:  // dic.keys() 获取字典中所有的key值
    for key in person.keys():
    
遍历字典的value:  // dic.values() 获取字典中所有的value值
    for value in person.values():
    
遍历字典的key和value:  // dic.items() 获取字典中所有的key和value
    for key,value in person.items():
    
遍历字典的项/元素:  // 与上不同的是输出会带小括号表示一个项
    for item in person.items()  

函数

def sum(num1,num2):
    c = num1 + num2
    print(c)

sum(1,2)
sum(num2=2,num1=1)

文件

文件打开与关闭

open(filePath,mode)  // 打开一个已经存在的文件,或者创建一个新文件
// filePath:文件路径,mode:访问模式
例如:f = open('test,txt','w'); f.write("hello world"); f.close()

访问模式:

r:只读,文件不存在则报错,默认模式;
w:只写入,文件已存在则覆盖,不存在则创建;
a:追加,文件已存在则在文件末尾追加,不存在则创建;
r+:读写,文件指针指向文件开头;
w+:读写,文件存在则覆盖,不存在则创建;
a+:读写,已存在则追加,不存在则创建;
rb:以二进制方式打开,只读;
wb:以二进制方式打开,文件已存在则覆盖,不存在则创建;
ab:以二进制方式打开,追加,文件已存在则在文件末尾追加,不存在则创建;
rb+:以二进制方式打开,读写,文件指针指向文件开头;
wb+:以二进制方式打开,读写,文件存在则覆盖,不存在则创建;
ab+:以二进制方式打开,读写,已存在则追加,不存在则创建;

文件的读写

f = open('test,txt','w')
f.write("hello world \n" * 2)

content = f.read()  # 读取全部
print(content)
# hello world
# hello world 

line = f.readline()   # 一行一行读取
print(line)
# hello world

lines = f.readlines()  # 读取多行,返回列表
# ['hello world \n','hello world \n']

f.close()

序列化和反序列化

序列化:对象 -> 字节序列

反序列化:字节序列 -> 对象

序列化

dumps():将Python对象变成json字符串

fp = open('text.txt','w')
name_list = ['zs','ls']

# 导入json模块
import json

# 序列化
names = json.dumps(name_list)

fp.write(names)
fp.close()

dupm():在将对象转换为字符串的同时,指定一个文件的对象,然后把转换后的字符串写入到这个文件里

fp = open('text.txt')
name_list = ['zs','ls']
import json

# 相当于dumps()中两步合并操作了
json.dump(name_list,fp)

fp.close()

反序列化

loads():将json字符串转换成Python对象

fp.open('text','r')
content = fp.read()
print(content)  # 直接输出是字符串类型的
import json

result = json.loads(content)
print(result)  # 输出列表类型

fp.close()

load()

fp.open('text','r')
import json

result = json.load(fp)
print(result)  # 输出列表类型

fp.close()

异常

try:
    可能出现异常的代码
except 异常的类型:
    友好的提示
# 例如:
try:
    fp = open('text.txt','r')
    fp.read()
except FileNotFoundError:
    print('文件不存在')

爬虫

urllib基本使用

# 定义url
url = 'http://www/baidu.com'

# 模拟浏览器向服务器发送请求
import urllib.request
response = urllib.request.urlopen(url)

# 获取响应中的页面源码
# read():返回的是字节形式的二进制数据
# 需要将二进制的数据转换为字符串,这个过程称为解码==decode(编码格式)
content = response.read().decode('utf-8')

print(content)

urllib的类型和方法

url = 'http://www.baidu.com'
response = urllib.request.urlopen(url)

# 一个类型
print(type(response))  # HTTPResponse类型

# 六个方法
# 按照一个字节一个字节去读
content1 = response.read()
# 数字参数表示返回多少个字节
content2 = response.read(5)
# 按行读,只能读取一行
content3 = response.readline()
# 按行读全部读完,同上
content4 = response.readlines()

# 读取状态码
code = response.getCode()

# 读取url地址
goal = response.getUrl()

# 读取状态信息-响应头
header = response.getheaders()

下载

url_page = 'http://www.baidu.com'

# 第一个参数:下载路径;第二个参数:文件的名字
# 图片、视频也同样这样下载,修改最后的文件类型就好了
urllib.request.urlretrieve(url_page,'baidu.html')

url的基本介绍

url的组成

例如:www.baidu.com/s?wd=爬虫&rsv…

协议主机端口号路径参数锚点
httpswww.baidu.com443swd=爬虫#

端口号

http  80
https  443
mysql  3306
oracle  1521
redis  6379
mongobd  27017

UA反爬的解决---请求对象的定制

import urllib
url = 'http://www.baidu.com'
# 获取User-Agent
headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36 Edg/105.0.1343.53'
}

# 这里采用这种传参写法是因为Request方法里有很多参数,不加的话可能会使得参数传递错误
request = urllib.request.Request(url=url,headers=headers)

response = urllib.request.urlopen(request)

content = response.read().decode('utf-8')

print(content)

编解码

get请求的quote方法

import urllib

url = 'https://www.baidu.com/s?wd='

# 定制请求
headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36 Edg/105.0.1343.53'
}

# 将中文编程Unicode编码的格式
name = urllib.parse.quote('爬虫')
# 将url与编码后的中文进行拼接
url = url + name

request = urllib.request.Request(url=url,headers=headers)

response = urllib.request.urlopen(request)

content = response.read().decode('utf-8')

print(content)

get请求的urlencode方法

应用于将多个参数同时生成一条Unicode编码

import urllib.parse
data = {
    'wd':'张三',
    'sex':'男'
}
a = urllib.parse.urlencode(data)
print(a)
# wd=%E5%BC%A0%E4%B8%89&sex=%E7%94%B7
# 案例:获取https://www.baidu.com/s?wd=%E7%88%AC%E8%99%AB的网页源码
import urllib.request
import urllib.parse

base_url = 'https://www/baidu.com/s?'
data = {
    'wd':'爬虫'
}

data_code = urllib.parse.urlencode(data)

url = base_url + data_code

headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36 Edg/105.0.1343.53'
}

request = urllib.request.Request(url=url,headers=headers)
response = urllib.request.urlopen(request)
content = response.read().decode('utf-8')
print(content)

post请求

post请求的参数,必须要进行编码,且参数是放在请求函数中

import urllib.request
import urllib.parse

url = 'https://www.baidu.com'
data = {
    'wd':'爬虫'
}

# post请求的参数,必须要进行编码
data_post = urllib.parse.urlencode(data).encode('utf-8')

headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36 Edg/105.0.1343.53'
}

# post请求的参数是不会直接拼接在url后面的,需要配置在请求对象定制的参数中
request = urllib.request.Request(url=url,data=data_post,headers=headers)
response = urllib.request.read().urlopen(request)
content = response.read().decode('utf-8')

# 字符串 -> json
import json
obj = json.loads(content)
print(obj)

ajax的请求

get请求

# get请求
# 获取豆瓣电影的第一页数据,并保存起来

import urllib.request
# import urllib.parse

url = 'https://m.douban.com/rexxar/api/v2/movie/recommend?refresh=0&start=0&count=20&selected_categories=%7B%22%E7%B1%BB%E5%9E%8B%22:%22%E7%88%B1%E6%83%85%22,%22%E5%9C%B0%E5%8C%BA%22:%22%E6%AC%A7%E7%BE%8E%22%7D&tags=%E7%88%B1%E6%83%85,%E6%AC%A7%E7%BE%8E'

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36 Edg/105.0.1343.53'
}

# 请求对象的定制
request = urllib.request.Request(url=url, headers=headers)
# 获取响应的数据
response = urllib.request.urlopen(request)
content = response.read().decode('utf-8')
# print(content)

# 下载数据到本地
# open()默认使用gbk的编码,如果我们想要保存汉字,那么需要在open中指定编码格式encoding='utf-8'
fp = open('douban.json', 'w', encoding='utf-8')
fp.write(content)

# 以上代码等同于以下
with open('douban1.json', 'w', encoding='utf-8') as fp:
    fp.write(content)