做java项目毕设前想通过爬虫爬取些数据存入数据库,从而在毕设中使用到,所以大致学习了一下python和爬虫做了下笔记。
基础知识
pip
pip通用的Python包管理工具。提供对Python包的查找、下载、安装、卸载功能。
变量类型
![](https://i-blog.csdnimg.cn/blog_migrate/649f5d11f81993a1088a76ea4faf65d7.png)
类型转换
函数 | 说明 |
int(x) | 将x转换为一个整数 |
float(x) | 将x转换为一个浮点数 |
str(x) | 将对象x转换为字符串 |
bool(x) | 将对象x转换为布尔值 |
int(x)
当boolean --> int时,true变为1,false变为0
当float --> int时,返回小数点前面的数据
bool(x)
当非0的数(包含正数和负数)转换成布尔类型,值为True;0转换成布尔类型,值为False
当字符串转换成布尔类型时,字符串中有内容,值为True
只要列表中有数据,那么强制类型转换成布尔类型时,就返回True,列表中没有数据则返回False
只要元组中有数据,那么强制类型转换成布尔类型时,就返回True,元组中没有数据则返回False
只要字典中有数据,那么强制类型转换成布尔类型时,就返回True,字典中没有数据则返回False
格式化输出
![](https://i-blog.csdnimg.cn/blog_migrate/19e26acedbcd05369c01ef442982e598.png)
字符串方法
![](https://i-blog.csdnimg.cn/blog_migrate/c75168ddbc25018f4f4e0555057ce4e6.png)
列表、字典、元组、集合区别:
![](https://i-blog.csdnimg.cn/blog_migrate/e439bc08ccb4bcb4fe6bfc0a2ea14a41.png)
列表
# !/usr/bin/env python
# -*-coding:utf-8 -*-
"""
# File : 032_list.py
# Time :2022/12/19 17:16
# Author :罗康明
# version :python 3.9.7
# Description:
"""
food_list = ["铁锅炖大鹅", "酸菜五花肉"]
# 从列表末尾加入
food_list.append("小酥肉")
print(food_list)
# 插入对应的下标中
food_list.insert(1, "肉末茄子")
print(food_list)
num_list = [1, 2, 3]
# 从列表末尾合并添加一个列表
food_list.extend(num_list)
print(food_list)
# 查找元素:in 、 not in
if "小酥肉" in food_list:
print("yep")
"""
删除元素方法
del:根据下标进行删除
pop:删除最后一个元素
remove:根据元素的值进行删除
"""
del food_list[4]
print(food_list)
food_list.pop()
print(food_list)
food_list.remove(2)
print(food_list)
元组
元组与列表类似,不同之处:元组的元素不能修改(元组只读)。元组使用小括号,列表使用中括号。
切片
切片是指对操作的对象截取其中一部分的操作。字符串、列表、元组都支持切片操作。
切片的语法:[起始:结束:步长],也可以简化使用 [起始:结束]
注意:选取的区间从"起始"位开始,到"结束"位的前一位结束(不包含结束位本身),步长表示选取间隔。
split_str = "hello world"
print(split_str[3: 7])
print(split_str[1:])
print(split_str[0:])
print(split_str[1:7:3])
![](https://i-blog.csdnimg.cn/blog_migrate/7005dcc78ab28974bafc0c15a328b06f.png)
字典
"""
# File : 038_dict.py
# Time :2022/12/19 18:55
# Author :罗康明
# version :python 3.9.7
# Description:
"""
gender = {"man": "男", "girl": "女"}
# 第一种方式通过dict["key"]访问对应value值
print(gender["man"])
print(gender["girl"])
# 当第一种方式获取字典中不存的key时,发生keyerror异常
# print(gender["name"])
# 第二种方式
print(gender.get("man"))
# 当第二种方式获取字典中不存的key时,返回None
print(gender.get("name"))
# 修改key对应的value值
gender["girl"] = "women"
print(gender.get("girl"))
# 往字典中新增key:value,当key不存在时新增,存在时修改
gender["age"] = 18
print(gender.get("age"))
# 删除
"""
del:1、删除字典中指定的某一个元素
2、删除整个字典
clear:1、清空字典,但是保留字典对象
"""
# 删除单个
del gender["man"]
print(gender.get("man"))
# 删除整个字典
# del gender
# 清空字典
gender.clear()
print(gender.get("girl"))
# 字典的遍历
# 遍历字典的key
for key in gender.keys():
print(key)
# 遍历字典的value
for value in gender.values():
print(value)
# 遍历字典的key和value
for key, value in gender.items():
print(key, value)
"""
输出结果:
man 男
girl women
age 18
"""
# 遍历字典的项/元素,每一项返回值为元组
for item in gender.items():
print(item)
"""
输出结果:
('man', '男')
('girl', 'women')
('age', 18)
"""
函数
定义函数:
def 函数名字([参数1,参数2...]):
代码
[return 返回值]
异常
try:
可能出现异常的代码
except 异常类型
处理代码
爬虫
爬取网页:爬取整个网页,包含网页中所有的内容
解析数据:将网页中你得到的数据进行解析
难点:爬虫和反爬虫之间的博弈
爬虫分类
通用爬虫
实例
百度、360、google、sougou等搜索引擎
功能
访问网页->抓取数据->数据存储->数据处理->提供检索服务robots协议一个约定俗成的协议,添加robots.txt文件,来说明本网站哪些内容不可以被抓取,起不到限制作用
自己写的爬虫无需遵守
网站排名(SEO)
1.根据pagerank算法值进行排名(参考个网站流量、点击率等指标)
2.百度竞价排名
缺点
1.抓取的数据大多是无用的
2.不能根据用户的需求来精准获取数据
聚焦爬虫
功能
根据需求,实现爬虫程序,抓取需要的数据
设计思路
1.确定要爬取的url
如何获取Url
2.模拟浏览器通过http协议访问url,获取服务器返回的html代码
如何访问
3.解析html字符串(根据一定规则提取需要的数据)
如何解析
反爬手段
User-Agent
User Agent中文名为用户代理,简称 UA,它是一个特殊字符串头,使得服务器能够识别客户使用的操作系统及版本、CPU 类型、浏览器及版本、浏览器染引擎、浏览器语言、浏览器插件等。
代理IP
西次代理
快代理
什么是高匿名、匿名和透明代理?它们有什么区别?
1.使用透明代理,对方服务器可以知道你使用了代理,并且也知道你的真实IP。
2.使用匿名代理,对方服务器可以知道你使用了代理,但不知道你的真实IP。
3.使用高匿名代理,对方服务器不知道你使用了代理,更不知道你的真实IP。
验证码访问
打码平台
云打码平台
动态加载网页
网站返回的是js数据 并不是网页的真实数据
selenium驱动真实的浏览器发送请求
数据加密
分析js代码
urllib
Python urllib 库用于操作网页 URL,并对网页的内容进行抓取处理。
urllib 包 包含以下几个模块:
urllib.request - 打开和读取 URL。
urllib.error - 包含 urllib.request 抛出的异常。
urllib.parse - 解析 URL。
urllib.robotparser - 解析 robots.txt 文件。
打开URL:
urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)
url:url 地址。
data:发送到服务器的其他数据对象,默认为 None。
timeout:设置访问超时时间。
cafile 和 capath:cafile 为 CA 证书, capath 为 CA 证书的路径,使用 HTTPS 需要用到。
cadefault:已经被弃用。
context:ssl.SSLContext类型,用来指定 SSL 设置。
"""
# File : 053_urllib.py
# Time :2023/1/6 15:43
# Author :罗康明
# version :python 3.9.7
# Description:使用urllib获取百度首页源码
"""
import urllib.request
# 1、定义一个url
url = "http://baidu.com/"
# 2、模拟浏览器向服务器发送请求
# reponse是HTTPResponse的类型
response = urllib.request.urlopen(url)
# 3、获取响应中的页面的源码
content = response.read().decode('utf-8')
# 4、输出内容
print(content)
一个类型六个方法
read([num])方法:无参时按照一个字节一个字节去读,有参时只读num个字节
readline():读取一行
readlines():一行一行读取,直到读取完毕
getcode():返回状态码。如果是返回200,则表示逻辑并没有出错
geturl():返回url地址
getheaders():获取状态信息
reponse是==HTTPResponse==的类型
response = urllib.request.urlopen(url)
response = urllib.request.urlopen(url)
reponse是HTTPResponse的类型
下载
# 下载网页
url = "https://baidu.com/"
urllib.request.urlretrieve(url, "baidu.html")
# 下载图片
url_img = "https://inews.gtimg.com/newsapp_bt/0/13108938126/1000"
urllib.request.urlretrieve(url_img, "leslie.jpg")
请求对象定制
第一个反爬手段:User-Agent
由于User_Agent头域的存在,服务器可以利用黑名单机制,实现User_Agent反爬。
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/108.0.0.0 Safari/537.36"
}
# 请求对象定制
# 因为参数顺序的问题,需要关键字传参
request = urllib.request.Request(url=url, headers=headers)
# Open the URL url, which can be either a string or a Request object.
response = urllib.request.urlopen(request)
content = response.read().decode("utf-8")
print(content)
解编码
get请求方式
①urllib.parse.quote()
"""
# File : 057_quote.py
# Time :2023/1/9 15:21
# Author :罗康明
# version :python 3.9.7
# Description:获取http://www.baidu.com/s?wd=张国荣网页源码
"""
import urllib.request
import urllib.parse
# https://www.baidu.com/s?wd=%E5%BC%A0%E5%9B%BD%E8%8D%A3
# 将”张国荣“三个字变成unicode编码的格式
name = urllib.parse.quote("张国荣")
url = "https://www.baidu.com/s?wd="+name
# 请求对象定制
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.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)
②urllib.parse.urlencode()
使用场景:多个参数的时候
"""
# File : 058_urlencode.py
# Time :2023/1/9 15:41
# Author :罗康明
# version :python 3.9.7
# Description:获取https://www.baidu.com/s?wd=张国荣网页源码
"""
import urllib.request
import urllib.parse
# https://www.baidu.com/s?wd=张国荣&sex=男
base_url = "http://www.baidu.com/s?"
# url后面参数要以字典的形式保存
data = {
"wd": "张国荣",
"sex": "男"
}
url = base_url + urllib.parse.urlencode(data)
# 请求对象定制
# 因为遭到反爬,所以加入cookie,没有反爬可不加
headers = {
"Cookie": 'BAIDUID=5487143C31BF5CEBDC5B7816674486CA:FG=1; BDUSS=9JY2IwaFdpYnpoTnhGR1NiLVJGZTBvS1pPQ1BnTGJFeUozSE5tYXpaUjN4YkppSVFBQUFBJCQAAAAAAAAAAAEAAAA0jrWw1tW8q8akudbKx87SAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHc4i2J3OItidW; BDUSS_BFESS=9JY2IwaFdpYnpoTnhGR1NiLVJGZTBvS1pPQ1BnTGJFeUozSE5tYXpaUjN4YkppSVFBQUFBJCQAAAAAAAAAAAEAAAA0jrWw1tW8q8akudbKx87SAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHc4i2J3OItidW; BIDUPSID=5487143C31BF5CEBDC5B7816674486CA; PSTM=1655200275; MCITY=-%3A; ZFY=oaETiXyDsBlLVd:AgHqUqhV0UQdUHhlTo40kezlhRl0E:C; BAIDUID_BFESS=5487143C31BF5CEBDC5B7816674486CA:FG=1; COOKIE_SESSION=2836_0_5_1_7_17_1_0_5_5_21_4_2837_0_4_0_1669819437_0_1669819433%7C5%230_0_1670573287%7C1%7C1; Hm_lvt_aec699bb6442ba076c8981c6dc490771=1669819434,1670578848; BAIDU_WISE_UID=wapp_1670761851771_906; BD_UPN=12314753; RT="z=1&dm=baidu.com&si=b6bt0tf7i7p&ss=lckaqa9k&sl=2&tt=6hg&bcn=https%3A%2F%2Ffclog.baidu.com%2Flog%2Fweirwood%3Ftype%3Dperf&ld=5wa&cl=e88&ul=jmr&hd=jo0"; BD_HOME=1; BA_HECTOR=202h81848ga00k0h24a4a4vr1hrng621l; BDRCVFR[feWj1Vr5u3D]=I67x6TjHwwYf0; BD_CK_SAM=1; PSINO=6; delPer=0; sugstore=0; H_PS_PSSID=36556_37646_37552_37521_38024_37139_37623_36920_37989_37793_37929_38041_26350_37881; H_PS_645EC=490eD6ZA59X9iEY9XG%2FJoZDN8Ak%2Fygs%2BM5HRRf%2FXDgqbyZYKCXERH2%2BvzTdMxV8bXnL9; BDSVRTM=238; baikeVisitId=565a919d-b4da-45eb-9d34-3adf968d165b',
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.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)
post请求方式
"""
# File : 059_post.py
# Time :2023/1/9 16:18
# Author :罗康明
# version :python 3.9.7
# Description:post请求百度翻译
"""
import urllib.request
import urllib.parse
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/108.0.0.0 Safari/537.36"
}
# post请求的参数,必须要进行编码
data = {
"kw": "spider"
}
data = urllib.parse.urlencode(data).encode("utf-8")
# 请求对象定制
# post请求的参数不会拼接在url后面,需要放在请求对象定制的参数中
request = urllib.request.Request(url, data, headers)
# 模拟浏览器向服务器发送请求
response = urllib.request.urlopen(request)
# 获取内容
content = response.read().decode("utf-8")
print(content)
ajax的get请求
爬取天天基金网一支股票的历史净值第一页
"""
# File : 061_fund.py
# Time :2023/1/9 17:27
# Author :罗康明
# version :python 3.9.7
# Description:爬取天天基金网一支股票的历史净值第一页
"""
import urllib.request
url = "https://fundf10.eastmoney.com/F10DataApi.aspx?type=lsjz&code=050026&page=1&sdate=2020-01-01&edate=2020-03-01&per=20"
headers = {
"Cookie": "qgqp_b_id=10ef72e7d60aa2a03786695b3fb475b9; EMFUND1=null; EMFUND2=null; EMFUND3=null; EMFUND4=null; EMFUND5=null; EMFUND6=null; EMFUND7=null; EMFUND0=null; EMFUND8=12-12%2015%3A39%3A11@%23%24%u5DE5%u94F6%u4EA7%u4E1A%u5347%u7EA7%u80A1%u7968A@%23%24007674; EMFUND9=01-09 17:22:43@#$%u5E7F%u53D1%u9053%u743C%u65AF%u77F3%u6CB9%u6307%u6570%u4EBA%u6C11%u5E01A@%23%24162719",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.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")
# 将数据写入本地
# fp = open("fund.json", "w", encoding="utf-8")
# fp.write(content)
with open("fund1.json", "w", encoding="utf-8") as fp:
fp.write(content)
爬取天天基金网一支股票的历史净值前十页
"""
# File : 062_fund.py
# Time :2023/1/10 17:02
# Author :罗康明
# version :python 3.9.7
# Description:爬取天天基金网一支股票的历史净值前十页
"""
import urllib.request
import urllib.parse
def create_request(current_page):
# https: // fundf10.eastmoney.com / F10DataApi.aspx?type = lsjz & code = 050026 & page = 1 & sdate = 2020 - 01 - 01 & edate = 2020 - 03 - 01 & per = 20
base_url = "https://fundf10.eastmoney.com/F10DataApi.aspx?"
# 组装url
data = {
"type": "lsjz",
"code": "050026",
"page": current_page,
"per": 20
}
data = urllib.parse.urlencode(data)
url = base_url + data
headers = {
# "Cookie": "qgqp_b_id=10ef72e7d60aa2a03786695b3fb475b9; EMFUND1=null; EMFUND2=null; EMFUND3=null; EMFUND4=null; EMFUND5=null; EMFUND6=null; EMFUND7=null; EMFUND0=null; EMFUND8=12-12%2015%3A39%3A11@%23%24%u5DE5%u94F6%u4EA7%u4E1A%u5347%u7EA7%u80A1%u7968A@%23%24007674; EMFUND9=01-09 17:22:43@#$%u5E7F%u53D1%u9053%u743C%u65AF%u77F3%u6CB9%u6307%u6570%u4EBA%u6C11%u5E01A@%23%24162719",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"
}
# 请求对象定制
request = urllib.request.Request(url=url, headers=headers)
return request
def get_content(request):
# 模拟浏览器向服务器发送请求
response = urllib.request.urlopen(request)
content = response.read().decode("utf-8")
with open("fund.js", "a", encoding="utf-8") as fp:
fp.write(content)
if __name__ == '__main__':
start_page = 1
end_page = 11
for page in range(start_page, end_page):
request = create_request(page)
get_content(request)
ajax的post请求
"""
# File : 063_kfc.py
# Time :2023/1/10 18:14
# Author :罗康明
# version :python 3.9.7
# Description:post请求kfc官网
"""
import urllib.request
import urllib.parse
url = "http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=cname"
headers = {
# "Cookie": "qgqp_b_id=10ef72e7d60aa2a03786695b3fb475b9; EMFUND1=null; EMFUND2=null; EMFUND3=null; EMFUND4=null; EMFUND5=null; EMFUND6=null; EMFUND7=null; EMFUND0=null; EMFUND8=12-12%2015%3A39%3A11@%23%24%u5DE5%u94F6%u4EA7%u4E1A%u5347%u7EA7%u80A1%u7968A@%23%24007674; EMFUND9=01-09 17:22:43@#$%u5E7F%u53D1%u9053%u743C%u65AF%u77F3%u6CB9%u6307%u6570%u4EBA%u6C11%u5E01A@%23%24162719",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"
}
data = {
"cname": "梧州",
"pid": "",
"pageIndex": 1,
"pageSize": 10
}
data = urllib.parse.urlencode(data).encode("utf-8")
# 请求对象定制
request = urllib.request.Request(url, data, headers)
# 模拟浏览器向服务器发送请求
response = urllib.request.urlopen(request)
# 获取内容
content = response.read().decode("utf-8")
print(content)
urllib异常
URLError\HTTPError
![](https://i-blog.csdnimg.cn/blog_migrate/ca78d4383dd04bd137d7275f7fbae129.png)
cookie登录
1、cookie中携带着登录信息,如果有登录后的cookie,那么便可以带着cookie进入登陆后的界面
2、referer,判断当前路径是不是由上一个路径进来的,一般做图片防盗链
Handler处理器
urllib.request.urlopen(url)--->不能定制请求头
urllib.request.Request(url,data,headers)--->可以定制请求头
Handler定制更高级的请求头(随着业务逻辑的复杂,请求对象的定制已经满足不了需求,动态cookie和代理不能使用请求对象的定制)
"""
# File : 066_handler.py
# Time :2023/1/14 20:17
# Author :罗康明
# version :python 3.9.7
# Description:使用Handler访问百度,获取网页源码
"""
import urllib.request
url = "http://www.baidu.com"
headers = {
# "Cookie": "qgqp_b_id=10ef72e7d60aa2a03786695b3fb475b9; EMFUND1=null; EMFUND2=null; EMFUND3=null; EMFUND4=null; EMFUND5=null; EMFUND6=null; EMFUND7=null; EMFUND0=null; EMFUND8=12-12%2015%3A39%3A11@%23%24%u5DE5%u94F6%u4EA7%u4E1A%u5347%u7EA7%u80A1%u7968A@%23%24007674; EMFUND9=01-09 17:22:43@#$%u5E7F%u53D1%u9053%u743C%u65AF%u77F3%u6CB9%u6307%u6570%u4EBA%u6C11%u5E01A@%23%24162719",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"
}
request = urllib.request.Request(url=url, headers=headers)
# handler build_opener open
# 1、获取handler对象
handler = urllib.request.HTTPHandler
# 2、获取opener对象
opener = urllib.request.build_opener(handler)
# 3、调用open方法
response = opener.open(request)
content = response.read().decode("utf-8")
print(content)
代理服务器
![](https://i-blog.csdnimg.cn/blog_migrate/bcf6644ac00937317a28d80888c86726.png)
"""
# File : 067_proxy.py
# Time :2023/1/15 16:07
# Author :罗康明
# version :python 3.9.7
# Description:
"""
import urllib.request
url = "https://www.baidu.com/s?wd=ip"
headers = {
# "Cookie": "BAIDUID=5487143C31BF5CEBDC5B7816674486CA:FG=1; BDUSS=9JY2IwaFdpYnpoTnhGR1NiLVJGZTBvS1pPQ1BnTGJFeUozSE5tYXpaUjN4YkppSVFBQUFBJCQAAAAAAAAAAAEAAAA0jrWw1tW8q8akudbKx87SAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHc4i2J3OItidW; BDUSS_BFESS=9JY2IwaFdpYnpoTnhGR1NiLVJGZTBvS1pPQ1BnTGJFeUozSE5tYXpaUjN4YkppSVFBQUFBJCQAAAAAAAAAAAEAAAA0jrWw1tW8q8akudbKx87SAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHc4i2J3OItidW; BIDUPSID=5487143C31BF5CEBDC5B7816674486CA; PSTM=1655200275; MCITY=-%3A; BD_UPN=12314753; H_PS_PSSID=36556_37646_37552_37521_38024_37139_36920_37989_37793_37929_38041_26350_37881; sugstore=0; H_PS_645EC=dc0av5l1JCAVWXBhIAZbXMKsrrUIRe%2BdSxBcMVFAwOcCjeMOj6cXgmOTpsDGADZKwrXC; BAIDUID_BFESS=5487143C31BF5CEBDC5B7816674486CA:FG=1; baikeVisitId=c7af13f3-52df-48ca-a167-3d88faafd8d5",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"
}
request = urllib.request.Request(url=url, headers=headers)
proxies = {
"http": "123.56.250.62:60080"
}
handler = urllib.request.ProxyHandler(proxies=proxies)
opener = urllib.request.build_opener(handler)
response = opener.open(request)
# 获取响应信息
content = response.read().decode("utf-8")
with open("proxy.html", "w", encoding="utf-8") as fp:
fp.write(content)
代理池
import urllib.request
import random
url = "https://www.baidu.com/s?wd=ip"
headers = {
# "Cookie": "BAIDUID=5487143C31BF5CEBDC5B7816674486CA:FG=1; BDUSS=9JY2IwaFdpYnpoTnhGR1NiLVJGZTBvS1pPQ1BnTGJFeUozSE5tYXpaUjN4YkppSVFBQUFBJCQAAAAAAAAAAAEAAAA0jrWw1tW8q8akudbKx87SAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHc4i2J3OItidW; BDUSS_BFESS=9JY2IwaFdpYnpoTnhGR1NiLVJGZTBvS1pPQ1BnTGJFeUozSE5tYXpaUjN4YkppSVFBQUFBJCQAAAAAAAAAAAEAAAA0jrWw1tW8q8akudbKx87SAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHc4i2J3OItidW; BIDUPSID=5487143C31BF5CEBDC5B7816674486CA; PSTM=1655200275; MCITY=-%3A; BD_UPN=12314753; H_PS_PSSID=36556_37646_37552_37521_38024_37139_36920_37989_37793_37929_38041_26350_37881; sugstore=0; H_PS_645EC=dc0av5l1JCAVWXBhIAZbXMKsrrUIRe%2BdSxBcMVFAwOcCjeMOj6cXgmOTpsDGADZKwrXC; BAIDUID_BFESS=5487143C31BF5CEBDC5B7816674486CA:FG=1; baikeVisitId=c7af13f3-52df-48ca-a167-3d88faafd8d5",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"
}
request = urllib.request.Request(url=url, headers=headers)
proxies_pool = [
{"http": "123.56.250.62:60080"},
{"http": "123.56.250.62:60081"},
]
proxies = random.choice(proxies_pool)
handler = urllib.request.ProxyHandler(proxies=proxies)
opener = urllib.request.build_opener(handler)
response = opener.open(request)
# 获取响应信息
content = response.read().decode("utf-8")
with open("proxy_pool.html", "w", encoding="utf-8") as fp:
fp.write(content)
解析
xpath
lxml库要安装在此路径下
![](https://i-blog.csdnimg.cn/blog_migrate/de655c1cdb6129a7cf96cccf731029a7.png)
安装:
![](https://i-blog.csdnimg.cn/blog_migrate/67d19d28cc9b559e7cb4e55e62ef6c52.png)
![](https://i-blog.csdnimg.cn/blog_migrate/21141667ad2798d67c1adc10c8e843b9.png)
基本语法
![](https://i-blog.csdnimg.cn/blog_migrate/9f6f381b3e84bb243b06f6c2392c8964.png)
"""
# File : 070_parse.py
# Time :2023/1/16 15:32
# Author :罗康明
# version :python 3.9.7
# Description:xpath的基本使用
"""
from lxml import etree
"""
xpath解析:
1、本地文件
etree.parse("**.html")
2、服务器响应的数据
etree.HTML(response.read().decode("utf-8"))
"""
tree = etree.parse("070_parse.html")
# 查找ul下的li
# li_list = tree.xpath("//body/ul/li/text()")
# 查找所有具有id属性的标签
# li_list = tree.xpath("//ul/li[@id]/text()")
# 找到id为beijing的标签
# li_list = tree.xpath("//ul/li[@id='beijing']/text()")
# 查找到id为beijng的li标签的class的属性值
# li_list = tree.xpath("//ul/li[@id='beijing']/@class")
# 查询id中包含z的li标签
# li_list = tree.xpath("//ul/li[contains(@id,'z')]/text()")
# 查询id值以s开头的li标签
# li_list = tree.xpath("//ul/li[starts-with(@id,'s')]/text()")
# 查询id为beijing,class为c1的
li_list = tree.xpath("//ul/li[@id='beijing' and @class='c1']/text()")
# 查询第二个ul的内容
li_list = tree.xpath("//body/ul[2]/li/text()")
# 查询id为beijing或id为shenzhen的
li_list = tree.xpath("//ul/li[@id='beijing']/text() | //ul/li[@id='shenzhen']/text()")
print(li_list)
html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title>Title</title>
</head>
<body>
<ul>
<li id="beijing" class="c1">北京</li>
<li id="shanghai">上海</li>
<li id="shenzhen">深圳</li>
<li id="guangzhou">广州</li>
</ul>
<ul>
<li>梧州</li>
<li>柳州</li>
<li>东莞</li>
<li>南宁</li>
</ul>
</body>
</html>
xpath解析练习
解析www.baidu.com的“百度一下”按钮
![](https://i-blog.csdnimg.cn/blog_migrate/b37b6b16a58bf35222b39115be0c13ed.png)
"""
# File : 071_parse_baidu.py
# Time :2023/1/19 15:38
# Author :罗康明
# version :python 3.9.7
# Description:获取百度源码,解析获取“百度一下”
"""
import urllib.request
from lxml import etree
url = "https://www.baidu.com/"
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.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")
# 解析源码内容
tree = etree.HTML(content)
result = tree.xpath("//input[@id='su']/@value")
print(result)
爬取站长素材前10页图片
# !/usr/bin/env python
# -*-coding:utf-8 -*-
"""
# File : 072_parse_pic.py
# Time :2023/1/19 16:04
# Author :罗康明
# version :python 3.9.7
# Description:爬取站长素材前十页图片
"""
import urllib.request
from lxml import etree
def create_request(page):
if page == 1:
url = "https://sc.chinaz.com/tupian/qinglvtupian.html"
else:
url = "https://sc.chinaz.com/tupian/qinglvtupian_{}.html".format(str(page))
headers = {
# "Cookie": "BAIDUID=5487143C31BF5CEBDC5B7816674486CA:FG=1; BDUSS=9JY2IwaFdpYnpoTnhGR1NiLVJGZTBvS1pPQ1BnTGJFeUozSE5tYXpaUjN4YkppSVFBQUFBJCQAAAAAAAAAAAEAAAA0jrWw1tW8q8akudbKx87SAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHc4i2J3OItidW; BDUSS_BFESS=9JY2IwaFdpYnpoTnhGR1NiLVJGZTBvS1pPQ1BnTGJFeUozSE5tYXpaUjN4YkppSVFBQUFBJCQAAAAAAAAAAAEAAAA0jrWw1tW8q8akudbKx87SAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHc4i2J3OItidW; BIDUPSID=5487143C31BF5CEBDC5B7816674486CA; PSTM=1655200275; MCITY=-%3A; BD_UPN=12314753; H_PS_PSSID=36556_37646_37552_37521_38024_37139_36920_37989_37793_37929_38041_26350_37881; sugstore=0; H_PS_645EC=dc0av5l1JCAVWXBhIAZbXMKsrrUIRe%2BdSxBcMVFAwOcCjeMOj6cXgmOTpsDGADZKwrXC; BAIDUID_BFESS=5487143C31BF5CEBDC5B7816674486CA:FG=1; baikeVisitId=c7af13f3-52df-48ca-a167-3d88faafd8d5",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"
}
# 请求对象定制
request = urllib.request.Request(url=url, headers=headers)
return request
def get_content(request):
# 获取handler对象
handler = urllib.request.HTTPHandler
# 获取opener对象
opener = urllib.request.build_opener(handler)
# 调用open方法
response = opener.open(request)
content = response.read().decode("utf-8")
return content
def download(content):
# urllib.request.urlretrieve("图片地址", "文件名字")
tree = etree.HTML(content)
# 解析获取图片url
img_url_list = tree.xpath("//div[@class='item']/img/@data-original")
# 解析获取图片名称
file_name_list = tree.xpath("//div[@class='bot-div']/a/@title")
for i in range(len(img_url_list)):
img_url = img_url_list[i]
url = "https:" + img_url
file_name = file_name_list[i]
name = "./pic/" + file_name + ".jpg"
urllib.request.urlretrieve(url=url, filename=name)
if __name__ == '__main__':
for page in range(1, 11):
# print(page)
# 请求对象的定制
request = create_request(page)
# 获取网页的源码
content = get_content(request)
# 下载
download(content)
JsonPath
JsonPath解析相对于xpath解析,jsonpath只能解析本地文件
![](https://i-blog.csdnimg.cn/blog_migrate/060242a16d933a53a25490bb1695ad9f.png)
基本语法
![](https://i-blog.csdnimg.cn/blog_migrate/bcfa9d718fbd3f0884d117fa2a38be36.png)
# !/usr/bin/env python
# -*-coding:utf-8 -*-
"""
# File : 073_jsonpath.py
# Time :2023/1/20 15:42
# Author :罗康明
# version :python 3.9.7
# Description:jsonpath语法练习
"""
import json
import jsonpath
obj = json.load(open("073_jsonpath.json", "r", encoding="utf-8"))
# 解析获取书店所有书的作者
# author_list = jsonpath.jsonpath(obj, "$.store.book[*].author")
# print(author_list)
# 获取所有作者
# author_list = jsonpath.jsonpath(obj, "$..author")
# print(author_list)
# 获取store的所有元素。所有的books和bicycle
# store = jsonpath.jsonpath(obj, "$.store.*")
# print(store)
# 获取store里面所有东西的price
# price_list = jsonpath.jsonpath(obj, "$.store..price")
# print(price_list)
# 获取第三本书
# book = jsonpath.jsonpath(obj, "$.store.book[2]")
# print(book)
# 最后一本书
# final_book = jsonpath.jsonpath(obj, "$.store.book[(@.length-1)]")
# print(final_book)
# 前面的两本书。
# books = jsonpath.jsonpath(obj, "$.store.book[:2]")
# print(books)
# 过滤出所有的包含isbn的书
# books = jsonpath.jsonpath(obj, "$.store.book[?(@.isbn)]")
# print(books)
# 过滤出价格低于10的书。
# books = jsonpath.jsonpath(obj, "$.store.book[?(@.price<10)]")
# print(books)
# 所有元素。
all_element = jsonpath.jsonpath(obj, "$..*")
print(all_element)
BeautifulSoup
BeautifulSoup和lxml一样,是一个html解析器,主要功能也是解析和提取数据
安装及创建:
![](https://i-blog.csdnimg.cn/blog_migrate/fc581791e326381b55f049066c692726.png)
基本使用
075_bs4.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div>
<ul>
<li id="l1">张三</li>
<li id="l2">李四</li>
<li>王五</li>
<a href="www.baidu.com" id="a1" class="a1">哈哈哈</a>
<span>呵呵呵</span>
</ul>
</div>
<a href="www.baidu.com" title="a2">百度</a>
<div id="d2">
<span>
hhh
</span>
</div>
<p id="p1" class="p1"></p>
</body>
</html>
# !/usr/bin/env python
# -*-coding:utf-8 -*-
"""
# File : 075_bs4.py
# Time :2023/1/21 15:27
# Author :罗康明
# version :python 3.9.7
# Description:bs4的基本使用
"""
from bs4 import BeautifulSoup
# 默认打开的编码格式是gbk,所以打开时要指定编码
soup = BeautifulSoup(open("075_bs4.html", encoding="utf-8"), "lxml")
# 根据标签名查找节点
# soup.a 找到的是第一个的a标签
soup.a
# 以字典的形式输出对应标签里的属性和属性值
soup.a.attrs
# bs4的一些函数
# 1、find
# 返回的是第一个符合条件的数据
soup.find("a")
# 根据title值找到对应的数据
soup.find("a", title="a2")
# 根据class值找到对应数据
soup.find("a", class_="a1")
# 2、find_all 以列表的形式返回所有符合条件的数据
soup.find_all("a")
# 想获取多个标签的数据,需要再find_all的参数中添加的是列表的数据
soup.find_all(["a", "span"])
# 想获取符合条件的前几个数据,添加limit条件
soup.find_all("li", limit=2)
# 3、select (推荐
# select方法返回的是一个列表
soup.select("a")
# 根据类选择器返回需要的值
soup.select(".a1")
# 根据id选择器返回需要的值
soup.select("#l1")
# 根据属性选择器找到对应的标签
# 查找到li标签中有id的标签
soup.select("li[id]")
# 找到li标签中id为l2的标签
soup.select("li[id='l2']")
# 层级选择器
# 后代选择器,找到的是div下面的li
soup.select("div li")
# 子代选择器 某标签的第一级子标签
soup.select("div > ul > li")
# 找到a标签和li标签的所有对象
soup.select("a,li")
# 节点信息
# 获取节点内容
soup.select("#d2")[0].get_text()
# 获取节点属性
soup.select("#p1")[0].attrs.get("class")
练习
# !/usr/bin/env python
# -*-coding:utf-8 -*-
"""
# File : 076_starbucks.py
# Time :2023/1/23 11:57
# Author :罗康明
# version :python 3.9.7
# Description:爬取星巴克数据并用bs4解析
"""
import urllib.request
from bs4 import BeautifulSoup
url = "https://www.starbucks.com.cn/menu/"
response = urllib.request.urlopen(url)
content = response.read().decode("utf-8")
soup = BeautifulSoup(content, "lxml")
# //ul[@class='grid padded-3 product']/li/a/strong/text()
name_list = soup.select("ul[class='grid padded-3 product'] li a strong")
for name in name_list:
print(name.get_text())
Selenium
==1.什么是selenium?==
(1) Selenium是一个用于Web应用程序测试的工具。
(2) Selenium 测试直接运行在浏览器中,就像真正的用户在操作一样。
(3)支持通过各种driver (FirfoxDriver, IternetExplorerDriver, OperaDriver, ChromeDriver)驱动真实浏览器完成测试。
(4)selenium也是支持无界面浏览器操作的。
==2.为什么使用selenium?==
模拟浏览器功能,自动执行网页中的js代码,实现动态加载
==3.如何安装selenium?==
(1)操作谷歌浏览器驱动下载地址http://chromedriver.storage.googleapis.com/index.html
(2)谷歌驱动和谷歌浏览器版本之间的映射表http://blog.csdn.net/huilansame/article/details/51896672
(3)查看谷歌浏览器版本谷歌浏览器右上角 - ->帮助 - - >关于
(4) pip install selenium
基本使用
# 创建浏览器操作对象
path = "chromedriver.exe"
browser = webdriver.Chrome(path)
# 访问网站
url = "http://www.baidu.com"
browser.get(url)
元素定位
![](https://i-blog.csdnimg.cn/blog_migrate/9d69fb72f8a28628a87db16d77107f2e.png)
元素信息
# !/usr/bin/env python
# -*-coding:utf-8 -*-
"""
# File : 079_element_positioning.py
# Time :2023/1/23 13:11
# Author :罗康明
# version :python 3.9.7
# Description:元素信息
"""
from selenium import webdriver
path = "chromedriver.exe"
browser = webdriver.Chrome(path)
url = "http://baidu.com"
browser.get(url)
input = browser.find_element_by_id('su')
# 获取标签属性
print(input.get_attribute("class"))
# 获取标签名字
print(input.tag_name)
# 获取元素文本
a = browser.find_element_by_link_text('新闻')
print(a.text)
交互
# !/usr/bin/env python
# -*-coding:utf-8 -*-
"""
# File : 081_selenium_interact.py
# Time :2023/1/23 13:30
# Author :罗康明
# version :python 3.9.7
# Description:selenium交互
"""
from selenium import webdriver
import time
path = "chromedriver.exe"
browser = webdriver.Chrome(path)
url = "https://www.baidu.com"
browser.get(url)
time.sleep(2)
# 获取文本框对象,并输入张国荣
input = browser.find_element_by_id('kw')
input.send_keys("张国荣")
time.sleep(1)
# 定位搜索按钮,模拟点击
button = browser.find_element_by_id('su')
button.click()
time.sleep(2)
# 滑到底部
js_bottom = "document.documentElement.scrollTop=100000"
browser.execute_script(js_bottom)
time.sleep(2)
# 定位下一页,模拟点击
next_page = browser.find_element_by_xpath("//div[@id='page']//a[last()]")
next_page.click()
time.sleep(2)
# 回到上一页
browser.back()
time.sleep(2)
# 回到第二页
browser.forward()
time.sleep(2)
# 退出
browser.quit()
requests
官方文档:https://cn.python-requests.org/zh_CN/latest/
response的属性以及类型:
类型 : models.Response
response.text : 获取网站源码
response.encoding : 访问或定制编码方式
response.url : 获取请求的url
response.content : 响应的字节类型,返回二进制数据
response.status_code:响应的状态码
response.headers : 响应的请求头信息
url = "http://www.baidu.com"
response = requests.get(url)
response.encoding = "utf-8"
get请求
"""
# File : 084_requests.py
# Time :2023/1/23 14:53
# Author :罗康明
# version :python 3.9.7
# Description:requests基本使用,get请求
"""
import requests
url = "https://www.baidu.com/s?"
headers = {
"Cookie": "BAIDUID=5487143C31BF5CEBDC5B7816674486CA:FG=1; BDUSS=9JY2IwaFdpYnpoTnhGR1NiLVJGZTBvS1pPQ1BnTGJFeUozSE5tYXpaUjN4YkppSVFBQUFBJCQAAAAAAAAAAAEAAAA0jrWw1tW8q8akudbKx87SAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHc4i2J3OItidW; BDUSS_BFESS=9JY2IwaFdpYnpoTnhGR1NiLVJGZTBvS1pPQ1BnTGJFeUozSE5tYXpaUjN4YkppSVFBQUFBJCQAAAAAAAAAAAEAAAA0jrWw1tW8q8akudbKx87SAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHc4i2J3OItidW; BIDUPSID=5487143C31BF5CEBDC5B7816674486CA; PSTM=1655200275; MCITY=-%3A; BD_UPN=12314753; H_PS_PSSID=36556_37646_37552_37521_37139_36920_37989_37793_37929_38041_26350_37881; sugstore=0; H_PS_645EC=80e6TtR6Suabysw1a1g4ctvlbreol0ZsWvpEtc0lY32%2BehcAQ9rNaNst9QtsgeewAnGI; BAIDUID_BFESS=5487143C31BF5CEBDC5B7816674486CA:FG=1; B64_BOT=1; baikeVisitId=5d6e3865-567c-4e36-b86a-7a5fcc3f1675",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"
}
data = {
"wd": "北京"
}
"""
url:请求路径
params:请求参数
headers:请求头
"""
response = requests.get(url=url, params=data, headers=headers)
response.encoding = "utf-8"
content = response.text
print(content)
post请求
# !/usr/bin/env python
# -*-coding:utf-8 -*-
"""
# File : 086_requests_post.py
# Time :2023/1/23 15:26
# Author :罗康明
# version :python 3.9.7
# Description:requests,post请求百度翻译
"""
import requests
import json
url = "https://fanyi.baidu.com/sug"
headers = {
"Cookie": "BAIDUID=5487143C31BF5CEBDC5B7816674486CA:FG=1; REALTIME_TRANS_SWITCH=1; FANYI_WORD_SWITCH=1; SOUND_PREFER_SWITCH=1; HISTORY_SWITCH=1; SOUND_SPD_SWITCH=1; BDUSS=9JY2IwaFdpYnpoTnhGR1NiLVJGZTBvS1pPQ1BnTGJFeUozSE5tYXpaUjN4YkppSVFBQUFBJCQAAAAAAAAAAAEAAAA0jrWw1tW8q8akudbKx87SAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHc4i2J3OItidW; BDUSS_BFESS=9JY2IwaFdpYnpoTnhGR1NiLVJGZTBvS1pPQ1BnTGJFeUozSE5tYXpaUjN4YkppSVFBQUFBJCQAAAAAAAAAAAEAAAA0jrWw1tW8q8akudbKx87SAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHc4i2J3OItidW; BIDUPSID=5487143C31BF5CEBDC5B7816674486CA; PSTM=1655200275; MCITY=-%3A; APPGUIDE_10_0_2=1; BAIDUID_BFESS=5487143C31BF5CEBDC5B7816674486CA:FG=1; BDRCVFR[feWj1Vr5u3D]=mk3SLVN4HKm; delPer=0; PSINO=7; BA_HECTOR=a40h010125ah8g25a08480nn1hsscq01l; ZFY=bX8f8pWkw1Wup2L5Rdo10:Am:BdAIyRZSyBKgkJM11fXM:C; H_PS_PSSID=36556_37646_37552_37521_37139_36920_37989_37793_37929_38041_26350_37881; Hm_lvt_64ecd82404c51e03dc91cb9e8c025574=1673252339,1674458645; Hm_lpvt_64ecd82404c51e03dc91cb9e8c025574=1674458645; ab_sr=1.0.1_NTliZmIwMjliM2RhZTkxNjcyMmYxMTVlMjEwNmViZDNkMjZmMTU1YmY0NDBkMjhiMGU3NjI3ODI2OTM5NjhiZTI3NDg1MDRhMjRjMjJjMDI5YTQzZDM2YjRmNTQ1ZGVkMGZlZjNlYTMwYjQ3M2I1NDYxYTM4NmI3NjU2N2U3MzU1OGY4MzhmYjhiOTg1ZDgzYzg2NTZkMDk3OTg4YTZlOTY0NzI0ZjlhN2NhZDM3MjY3Y2YwNzQzNThiZjM3MjU2",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"
}
data = {
"kw": "spider"
}
"""
url:请求路径
data:请求参数
headers:请求头
"""
response = requests.post(url=url, data=data, headers=headers)
content = response.text
obj = json.loads(content)
print(obj)
"""
总结:
1、post请求,不需要编解码
2、post请求的参数是data
3、不需要定制请求对象
"""
代理
"""
# File : 087_requests_proxy.py
# Time :2023/1/26 21:24
# Author :罗康明
# version :python 3.9.7
# Description:requests代理使用
"""
import requests
url = "http://httpbin.org/ip"
proxy = {
"http": "http://120.77.223.152:16817"
}
response = requests.get(url=url, proxies=proxy)
# response.encoding = "utf-8"
content = response.text
with open("proxy_requests.html", "w", encoding="utf-8") as fp:
fp.write(content)