python基础与爬虫笔记

做java项目毕设前想通过爬虫爬取些数据存入数据库,从而在毕设中使用到,所以大致学习了一下python和爬虫做了下笔记。

大致过了一遍视频:https://www.bilibili.com/video/BV1Db4y1m7Ho/?spm_id_from=333.1007.top_right_bar_window_custom_collection.content.click

基础知识

pip

pip通用的Python包管理工具。提供对Python包的查找、下载、安装、卸载功能。

变量类型

类型转换

函数

说明

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

格式化输出

字符串方法

列表、字典、元组、集合区别:

列表

# !/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])

字典

"""
# 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

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)

代理服务器

"""
# 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库要安装在此路径下

安装:

基本语法
"""
# 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的“百度一下”按钮

"""
# 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只能解析本地文件

基本语法
# !/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解析器,主要功能也是解析和提取数据

安装及创建:

基本使用

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)

元素定位

元素信息

# !/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)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值