[Study]Python Spider
Posted Spring-_-Bear
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Study]Python Spider相关的知识,希望对你有一定的参考价值。
文章目录
一、Python 基础
1.1 pip
指令 | 含义 |
---|---|
pip -V | 查看 pip 版本 |
pip install pagckageName | 安装指定的包 |
pip uninstall packageName | 删除指定的包 |
pip list | 显示已安装的包 |
pip freeze | 显示已安装的包,并且以指定的格式显示 |
pip install packageName -i url | 修改 pip 下载源 |
下载源:
1.2 数据类型
-
Number:数字(int、
long、float、bool、complex)# int money = 5000 # float money1 = 55.55 # boolean gender = True sex = False # complex complexNum1 = 1 + 2j complexNum2 = 1 + 2j print(complexNum1 + complexNum2)
-
String:字符串
# 字符串 hello = 'hello' world = "world" helloWorld = '"HelloWorld"' hello_world = "'Hello World'"
-
List:列表
# 列表 classList = ['软件1901', '软件1902'] # <class 'list'> print(type(classList))
-
Tuple:元组。元组与列表的区别在于元组不可修改,定义只有一个元素的元组时需要在元素后添加一个逗号以标识该变量表示的是元组
cities = ('武汉') # output: <class 'str'> print(type(cities)) # output: <class 'tuple'> cities = ('武汉',) print(type(cities))
-
Set:集合
# 集合 classSet = '软件1901', '软件1902' # <class 'set'> print(type(classSet))
-
Dictionary:字典
# 字典 personDict = 'name': 'Spring-_-Bear', 'age': 22 # <class 'dict'> print(type(personDict))
-
数据类型转换:
函数 说明 int(x) 将 x 转换为一个整数 float(x) 将 x 转换为一个浮点数 str(x) 将 x 转换为一个字符串 bool(x) 将 x 转换为一个布尔值 # output: 55 print(int(55.55)) # output: 1 print(int(True)) # output: 0 print(int(False)) # output: True print(str(True)) # output: False print(str(False)) # output: False 0 为假,非 0 为真 print(bool(0)) print(bool(0.0)) print(bool(0 + 0j)) print(bool('')) print(bool([])) print(bool(())) print(bool())
1.3 运算符
与 | 或 | 非 |
---|---|---|
and | or | not |
运算符 | 描述 | 实例 |
---|---|---|
+ | 加 | 10 + 20 = 30 |
- | 减 | 10 - 20 = -10 |
* | 乘 | 10 * 20 = 200 |
/ | 除 | 50 / 2 = 25.0,100 / 3 = 33.333333333333336 |
// | 取整除 | 50 // 2 = 25,100 // 3 = 33 |
% | 取余 | 100 % 3 = 1 |
** | 指数 | 2 ** 10 = 1024 |
() | 括号 | 提升运算优先级 |
-
复合赋值:
a, b, c = 1, 2, 3 # output: 1 2 3 print(a, b, c)
-
字符串拼接:
# output: TypeError: can only concatenate str (not "int") to str print('123' + 456) # output: 你爱我 我爱你 蜜雪冰城甜蜜蜜你爱我 我爱你 蜜雪冰城甜蜜蜜你爱我 我爱你 蜜雪冰城甜蜜蜜 print('你爱我 我爱你 蜜雪冰城甜蜜蜜' * 3)
1.4 关键字
# 33 个 Python 关键字
False None True and as assert break class
continue def del elif else except finally for
from global if import in is lambda nonlocal
not or pass raise return try while with
yield
1.5 流程控制
-
if-elif-else:
score = int(input('Please input your score:')) if score >= 90: print('优秀') elif score >= 80: print('良好') elif score >= 60: print('及格') else: print('不及格')
-
for:
# range(10) -> [0, 10) for i in range(10): print(i) # range(5, 10) -> [5,10) for i in range(5, 10): print(i) # range(1,10,2) -> [1,3,5,7,9] for i in range(1, 10, 2): print(i) # 通过下标遍历列表 nameList = ['张三', '李四', '王五', '赵六'] for i in range(len(nameList)): print(nameList[i])
1.6 字符串函数
函数 | 功能 |
---|---|
len(s) | 返回字符串长度 |
s1.find(s2) | 返回 s2 在 s1 中首次出现的下标,未出现则返回 -1 |
s1.startswith(s2) | 判断 s1 是否以 s2 开头,是则返回 True,否则返回 False |
s1.endswith(s2) | 判断 s1 是否以 s2 结尾,是则返回 True,否则返回 False |
s1.count(s2) | 统计 s2 在 s1 中出现的次数 |
s1.replace(s2, s3) | 将 s1 中所有的 s2 替换为 s3 |
s1.split(s2) | 以 s2 为分隔符切割 s1,返回列表 |
s1.upper() | 将 s1 转换为全大小 |
s1.lower() | 将 s1 转换为全小写 |
s1.strip() | 去除 s1 的首尾空格 |
s1.join(s2) | 在 s2 中间隔插入 s1,'23'.join('11111') => '1231231231231' |
1.7 列表函数
函数 | 功能 |
---|---|
list1.append(obj) | 将 obj 追加到列表 list1 尾 |
list1.insert(index, obj) | 将 obj 插入到列表 list1 的 index 位置 |
list1.extend(list2) | 将列表 list2 中的元素追加到 list1 中 |
del list[index] | 根据下标 index 移除列表 list1 中的元素 |
list1.pop() | 移除列表 list1 中的最后一个元素 |
list1.remove(key) | 根据 key 移除列表 list1 中的元素 |
# 列表查找
cities = ['武汉', '北京', '上海', '深圳']
city = input('请输入您想查找的城市名称:')
if city in cities:
print('成功找到%s' % city)
else:
print('查找失败')
if city not in cities:
print('%s不在城市列表中' % city)
else:
print('成功找到%s' % city)
1.8 字典函数
-
字典查询:
person = 'name': '张三', 'age': 22 # output: 22 若 key 不存在则抛出异常 print(person['age']) # output: 张三 若 key 不存在不抛出异常并返回 None print(person.get('name')) # output: 180 若 key 不存在则返回指定的默认值 print(person.get('height', 180))
-
字典修改:
person = 'name': '张三', 'age': 22 person['name'] = '法外狂徒'
-
字典添加:
person = 'name': '张三', 'age': 22 person['sex'] = True
-
字典删除:
person = 'name': '张三', 'age': 22 # 根据 key 删除字典中的某一项 del person['age'] # 删除整个字典 del person # 清空字典中的所有元素 person.clear()
-
字典遍历:
person = 'name': '张三', 'age': 22 # 遍历所有的 key for key in person.keys(): print(key) # 遍历所有的 val for val in person.values(): print(val) # key-val for key, val in person.items(): print('%s-%s' % (key, val)) # (key, val) for item in person.items(): print(item)
1.9 切片
切片语法格式:[start, end, step]
,从 [start, end)
中以步长 step
为单位截取子部分
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
# output: [1, 3, 5, 7, 9]
print(numbers[0: len(numbers): 2])
1.10 函数
def add(a, b):
return a + b
print(add(2, 3))
1.11 IO
在 Python 中使用 open(path, mode)
函数可以打开一个已经存在的文件或者创建一个新文件
模式 | 说明 |
---|---|
r | 以只读模式打开文件并将文件指针置于文件开头,若文件不存在则报错(默认模式) |
w | 以只写模式打开文件,若文件已存在则覆盖,不存在则新建 |
a | 以追加模式打开文件,若文件已存在则将文件指针置于文件末尾,不存在则新建 |
r+ | 打开一个文件用于读写,文件指针置于文件开头 |
w+ | 打开一个文件用于读写,若文件已存在则覆盖,不存在则新建 |
a+ | 打开一个文件用于追加,若文件已存在则将文件指针置于文件末尾,不存在则新建 |
rb | 以二进制格式打开文件用于只读,文件指针置于文件开头 |
wb | 以二进制方式打开文件用于只写,若文件不存在则新建,已存在则覆盖 |
ab | 以二进制方式打开文件用于追加,若文件已存在则将指针置于文件末尾,不存在则新建 |
rb+ | 以二进制格式打开一个文件用于读写,文件指针置于文件开头 |
wb+ | 以二进制格式打开一个文件用于读写,若文件不存在则新建,已存在则覆盖 |
ab+ | 以二进制格式打开文件用于追加读写,若文件已存在则将指针置于文件末尾,不存在则新建 |
# 文件写入
fp = open('file.txt', 'a')
fp.write("Hello python!\\n" * 5)
fp.close()
fp = open('file.txt', 'r')
# 文件读取:默认情况下一字节一字节地读,读完整个文件
content = fp.read()
print(content)
# 文件读取:读取一行
line = fp.readline()
print(line)
# 文件读取:读取所有行,返回列表
lines = fp.readlines()
print(lines)
fp.close()
1.12 序列化
-
dumps
序列化与loads
反序列化:-
dumps
对象序列化import json person = 'name': 'Spring-_-Bear', 'age': 22 # 序列化,将 Python 对象转换为 json 字符串 person = json.dumps(person) # output: <class 'str'> print(type(person)) fp = open('json.txt', 'w') fp.write(person) fp.close()
-
loads
反序列化import json fp = open('json.txt', 'r') content = fp.read() # 反序列化 obj = json.loads(content) print(obj) fp.close()
-
-
dump 序列化与 load 反序列化:
-
dump
对象序列化import json person = 'name': 'Spring-_-Bear', 'age': 22 fp = open('json.txt', 'w') # 序列化,将 Python 对象转换为 json 字符串的同时写入文件 json.dump(person, fp) fp.close()
-
load
反序列化import json fp = open('json.txt', 'r') obj = json.load(fp) print(obj) fp.close()
-
1.13 异常
try:
num = 1 / 0
print(num)
except ArithmeticError:
print('500 internal exception')
二、urllib
2.1 基本使用
import urllib.request
url = 'http://www.baidu.com'
# 发起请求
response = urllib.request.urlopen(url)
# <class 'http.client.HTTPResponse'>
print(type(response))
# 获取响应的内容,逐字节读取直至读完
content = response.read().decode('utf-8')
# 逐行读取
line = response.readline()
# 读取所有行
lines = response.readlines()
# 响应码
code = response.getcode()
# 请求的 url
url = response.geturl()
# 响应头
headers = response.getheaders()
2.2 文件下载
import urllib.request
url = 'https://whut.springbear2020.cn/static/img/WHUT.png'
filename = 'WHUT.jpg'
urllib.request.urlretrieve(url, filename)
2.3 请求对象定制
import urllib.request
url = 'https://www.baidu.com'
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'
# 请求对象定制
request = urllib.request.Request(url=url, headers=headers)
# 发起请求
response = urllib.request.urlopen(request)
# 获取响应内容
content = response.read().decode('utf-8')
print(content)
2.4 GET 请求
-
quote
方法将内容编码为 Unicodeimport urllib.request import urllib.parse data = input('Input the content you want to baidu:') # quote 方法将内容编码为 Unicode url = 'https://www.baidu.com/s?wd=' + urllib.parse.quote(data) 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' # 请求对象定制 request = urllib.request.Request(url=url, headers=headers) # 发起请求 response = urllib.request.urlopen(request) # 读取响应内容 content = response.read().decode('utf-8') print(content)
-
urlencode
方法将字典数据拼接为 key&val 形式import urllib.parse data = 'name': '陆平彪', 'sex': '男' url = 'https://www.baidu.com/s?wd=' + urllib.parse.urlencode(data) print(url)
2.5 POST 请求
import urllib.parse
import urllib.request
import json
url = 'https://fanyi.baidu.com/sug'
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'
data =
'kw': 'spider'
# 对请求参数内容进行编码,并转为字节数据
bytesData = urllib.parse.urlencode(data).encode('utf-8')
# 请求对象定制
request = urllib.request.Request(url, bytesData, headers)
# 发起请求,获取响应
response = urllib.request.urlopen(request)
content = response.read().decode('utf-8')
with open('fanyi.json', 'w', encoding='utf-8') as fp:
fp.write(content)
fp.close()
2.6 代理
import urllib.request
url = 'https://movie.douban.com/j/chart/top_list?type=17&interval_id=100%3A90&action=&start=0&limit=20'
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'
proxies =
'http': '188.131.233.175:8118'
# 创建代理处理器 handler
handler = urllib.request.ProxyHandler(proxies=proxies)
# 依据 handler 生成 opener
opener = urllib.request.build_opener(handler)
# 请求对象定制
request = urllib.request.Request(url=url, headers=headers)
# 通过 opener 发起请求
response = opener.open(request)
content = response.read().decode('utf-8')
print(content)
三、内容解析
3.1 xpath
-
安装 lxml:
pip install lxml -i https://pypi.douban.com/simple
-
lxml 的两种使用方式:
from lxml import etree # 解析本地 html 页面 localHtml = etree.parse('xpath.html') # 解析响应的 html 页面 etree.HTML(response.read().decode('utf-8'))
-
xpath 基本语法:
方式 示例 说明 路径查询 // 查找所有子孙节点,不考虑层级关系 路径查询 / 查找父节点下的子节点 谓词查询 //div[@id] 查找拥有 id 属性的 div 谓词查询 //div[@id=“main”] 查询 id=main 的 div 属性查询 //div[@id=“main”/@class] 查询 id=main 的 div 的 class 属性值 模糊查询 //div[contains(@id, “he”)] 查询 id 值包含 he 的 div 模糊查询 //div[starts-with(@id, “he”)] 查询 id 值以 he 开头的 div 内容查询 //div/text() 查询 div 的文本值 逻辑运算 //div[@id=“head” and @class=“c1”] 查询 id=head 且 以上是关于[Study]Python Spider的主要内容,如果未能解决你的问题,请参考以下文章
全网最详细使用Scrapy时遇到0: UserWarning: You do not have a working installation of the service_identity modul