爬虫
首先 了解所要爬取数据的网页 的数据获取方式
查看General 中的Request Method
一般是这两种 一个是 GET 另一个是POST
模拟浏览器发送请求
发送 GET方式的 请求:找到对应网站 的Network中 找到Response Headers里面的User-Agent
发送 POST方式的 请求:找到对应网站 的Network中 找到Form Data里面的数据
request
1:模块安装
requests: pip install requests
请求时:
request.get(verify = False)
有时需要添加 verify = False 去掉安全验证
charset
查看网页是以什么来编码的
requ.encoding = ‘字符集’
防止IP被封
访问完页面后 记得关闭请求 resp.close()
Json
将服务器返回的内容直接处理成json() 即 字典 dict
数据导入到CSV
导入csv模块
import csv
f = open(“data.csv”, mode=”w”, encoding=”utf-8″) // 创建data.csv文件
csvwriter = csv.writer(f)
csvwriter.writerow(dic.values()) //以行写入
//图片
img_name = src.split(“/”)[-1] # 拿到url中的最后一个/以后的内容
with open(“img/” + img_name, mode=”wb”) as f:
f.write(img_resp.content) # 图片内容写入文件
Re
特点:运行速度块、效率高、准确性高
以正则表达式 结合html源带码 来定位解析获取数据
重点:(?P<分组名字>.*?) 和 finditer【返回的是迭代器】,从迭代器中拿到内容需要.group()
相关知识点
模块引入
import re
Regular Expression 正则表达式
贪婪匹配
.*
惰性匹配(写爬虫运用最多)
.*?
1、re.findall() #匹配字符串中所有的符合正则的内容
2、re.finditer() #finditer: 匹配字符串中所有的内容【返回的是迭代器】,从迭代器中拿到内容需要.group()
3、re.search() # 找到第一个结果就返回, 返回的结果是match对象, 拿到数据同样需要 .group()
4、re.match() # 从头开始匹配 .group()
5、预加载正则表达式 即先规定解析数据的正则表达式
obj = re.compile(r”d+”,re.S)
re.S: 让点能匹配换行
(?P<分组名字>正则) 可以单独从正则匹配的内容中进一步提取内容
(?P<分组名字>.*?)
案例
# 模拟html源带码
s = “””
<div class=’jay’><span id=’1′>郭麒麟</span></div>
<div class=’jj’><span id=’2′>宋轶</span></div>
<div class=’jojin’><span id=’3′>大聪明</span></div>
<div class=’salar’><span id=’4′>范晓萱</span></div>
<div class=’kolin’><span id=’5′>可乐</span></div>
“””
# (?P<分组名字>正则) 可以单独从正则匹配的内容中进一步提取内容
obj = re.compile(r”<div class='(?P<cla>.*?)’><span id='(?P<id>d+)’>(?P<wahaha>.*?)</span></div>”, re.S) # re.S: 让点能匹配换行
result = obj.finditer(s)
for it in result:
print(it.group(“cla”))
print(it.group(“wahaha”))
print(it.group(“id”))
Bs4
代表一类的解析方案 执行效率不高
根据html超文本的标签和属性 来定位获取解析获取数据
注意:指定html解析器 “html.parser”
相关知识点
BeautifulSoup
安装
pip install bs4
导入
from bs4 import BeautifulSoup
1、获取页面
resp = requests.get(url)
2、解析数据
把页面源代码交给BeautifulSoup进行处理,生成bs对象
bsObj = BeautifulSoup(resp.text, “html.parser”)
# html.parser 采用BeautifulSoup是会将页面源代码直接当成html处理可能会出问题 报错 所以直接指 定为html解释器
3、从bsObj中查找数据
find(标签, 属性=值)
find_all(标签, 属性=值)
如: table = bsObj.find(“table”, class_=”hq_table”)
命名 = table.text //拿到内容
案例演示
# 1、自定义获取html代码
page = “””
<table class=”hq_table”>
<ul >
<li>第一个li</li>
<li>第二个li</li>
<li>第三个li</li>
<li>第四个li</li>
<li>第五个li</li>
</ul>
<ul>
<li>第二个ul中的li</li>
</ul>
</table>
“””
# 2、解析数据
bsObj = BeautifulSoup(page, “html.parser”) # 指定html解析器
# 3、从 bsObj中查找数据 查找ul元素 ,且类名为hq_table的数据
data = bsObj.find(“table”, class_=”hq_table”) # class是python的关键字
# data = bsObj.find(“table”, attrs={“class”: “hq_table”}) # 和上一行意思一样
# 4、进一步查找
uls = data.find_all(‘ul’) # 获取ul下的所有li元素, 返回数组
for ul in uls: # 遍历两个ul
lis = ul.find_all(‘li’) # 找到每个ul中的li, 返回数组
first = lis[0].text # 获取第一个ul里的第一个li
print(first)
Xpath
解析数据(流行 简便)
xpath 是在XML文档中搜索内容的一门语言
xpath 同样也是在html源带码中 以路径的样式 来定位获取数据
相关知识点
安装lxml模块
pip install lxml -i xxxxx
导入模块
from lxml import etree
解析数据
tree = etree.parse(html文件)
etree.XML(XML文件)
etree.HTML(html页面源带码)
查找数据
tree.xpath(“路径/text()”)
tree.xpath(“/book/author//nick/text()”) # // 后代
tree.xpath(“/book/author/*/nick/text()”) # * 任意的节点,通配符
tree.xpath(“….a/@href”) 拿到链接
tree.xpath(“/html/body/ol/li/a[@href=’dapao’]/text()”)
案例演示
# 爬取猪八戒网站
# 1.拿到页面源代码
# 2.提取和数据解析
import requests
from lxml import etree
url = “https://lps.zbj.com/search/f/?kw=saas”
resp = requests.get(url)
# print(resp.text)
resp.close()
# 解析
html = etree.HTML(resp.text)
# 拿到每一个服务商的div
divs = html.xpath(“/html/body/div[6]/div/div/div[2]/div[5]/div[1]/div”)
for div in divs: # 拿到每一个服务商信息
company = div.xpath(“./div/div/a[1]/div/p/text()”)[1] # 返回内容为数组,根据返回数据区0或1
location = div.xpath(“./div/div/a[1]/div/div/span/text()”)[0]
price = div.xpath(“./div/div/a[2]/div[2]/div[1]/span[1]/text()”)[0].strip(“¥”) # 去除¥
title = “saas”.join(div.xpath(“./div/div/a[2]/div[2]/div[2]/p/text()”)) # 去除saas
sold = div.xpath(“./div/div/a[2]/div[2]/div[1]/span[2]/text()”)[0]
print(company, location, price, title, sold, sep=(” | “)) # 以 | 隔开
CSS解析数据的用法
通过html的元素和属性定位数据,获取数据
优点,方便:循环爬虫多个模块数据时,若某一模块的定位的路径不存在,直接返回空,而不会像Re、Bs4、Xpath会直接报错
相关知识点
# 需要模块
import parsel
# css选择器解析
selector = parsel.Selector(解析的内容)
# 定位
selector.css(‘要定位的元素属性值’)
# 获取内容
1、selector.css(‘要定位的元素属性值’).get() # 得到定位中的内容
2、.getall() # 获取所有内容 返回一个列表
3、.extract() # 获取内容 返回列表
案例演示
import requests
import parsel
url = “https://www.biquge.biz/58_58780/161880.html
“
# 获取页面内容
respond = requests.get(url).text
#print(respond)
# css选择器解析
selector = parsel.Selector(respond)
# 定位
novle = selector.css(‘.bookname h1::text’).get()
print(novle)
用户登录
# 登录 -> 得到cookie
# 带着cookie 去请求到书架的url -> 书架上的内容
# 必须得把上面的两个操作连起来
# 我们可以使用session进行请求 -> session你可以认为是一连串的请求。 在这个过程中的cookie不会丢失
防盗链
header = {
“User-Agent”: “Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36”,
# 防盗链:溯源, 当前本次请求的上一级是谁
“Referer”: “https://www.pearvideo.com/video_1750164” # 即url
}
多线程
# 线程, 进程
# 进程是资源单位, 每个进程至少要有一个线程
# 线程是执行单位
启动每一个程序默认都会有一个 主线程导入包
from threading import Thread # 线程类
# 子线程执行
def fn():
for i in range(100):
print(“func”, i)
if __name__ == ‘__main__’: # 主线程
t = Thread(target=fn) # 创建子线程并给线程安排任务
t.start() # 多线程状态为可以开始工作状态, 具体的执行时间由CPU决定
# 主线程执行
for i in range(100):
print(“main”, i)
线程池
# 导入包
from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
# 线程池执行操作
def fn(name):
for i in range(1000):
print(name, i)
if __name__ == ‘__main__’:
# 创建线程池 五十个子线程同时执行
with ThreadPoolExecutor(50) as t:
for i in range(100):
t.submit(fn, name=f”线程{i}”)
# 等待线程池中的任务全部执行完毕,才继续执行(守护)
print(“123”)
协程
注意:
下方中所讲的一切,都是在单线程的条件下
协程: 当程序遇见了IO操作的时候, 可以选择性的切换到其他任务上
在微观上是一个任务一个任务的进行切换,切换条件一般就是IO操作
在宏观上,我们能看到的其实就是多个任务一起在执行
多任务异步操作
import time
def func():
print(“我爱黎明”)
time.sleep(3) # 让当前的线程处于阻塞的状态, CPU是不工作的
print(“我其实爱美女”)
if __name__ == ‘__main__’ :
func()
input() 程序也是处于阻塞状态
requests.geet(bilibili) 在网络请求返回数据之前,程序也是处于阻塞状态的
一般情况下,当程序处于 IO操作的时候, 线程都会处于阻塞状态
注意:
上方所讲的一切,都是在单线程的条件下
- 协程编写
- 用法
# python编写协程的程序
import asyncio
import time
async def func():
print(“你好啊,我叫ipipgo”)
if __name__ == ‘__main__’:
g = func() # 此时的函数是异步协程函数, 此时函数执行得到的是一个协程对象
# print(g)
asyncio.run(g) # 协程程序运行需要asyncio模块支持
- 第一个案例
async def func1():
print(“你好啊,外婆家”)
# time.sleep(3) # time是同步操作, 此时异步就中断了
await asyncio.sleep(3) # 异步操作的代码, await表示挂起
print(“你好啊,外婆家”)
async def func2():
print(“你好啊,王建孤鸿”)
# time.sleep(3)
await asyncio.sleep(2)
print(“你好啊,王建孤鸿”)
async def func3():
print(“你好啊,李学庆”)
# time.sleep(3)
await asyncio.sleep(4)
print(“你好啊,李学庆”)
if __name__ == ‘__main__’:
f1 = func1()
f2 = func2()
f3 = func3()
tasks = [
f1, f2, f3
]
t1 = time.time()
# 一次性启动多个任务(协程)
asyncio.run(asyncio.wait(tasks)) # 启动列表
t2 = time.time()
print(t2-t1)
- 第一个案例的第二种写法
# 第二个案例
async def func1():
print(“你好啊,外婆家”)
# time.sleep(3) # time是同步操作, 此时异步就中断了
await asyncio.sleep(3) # 异步操作的代码, await表示挂起
print(“你好啊,外婆家”)
async def func2():
print(“你好啊,王建孤鸿”)
# time.sleep(3)
await asyncio.sleep(2)
print(“你好啊,王建孤鸿”)
async def func3():
print(“你好啊,李学庆”)
# time.sleep(3)
await asyncio.sleep(4)
print(“你好啊,李学庆”)
async def main():
# 第一种写法
# f1 = func1()
# await f1 # 一般await挂起操作放在协程对象前面
# 第二种写法(推荐)
tasks = [
# func1(),
# func2(),
# func3()
asyncio.create_task(func1()), # 解决了版本报错问题
asyncio.create_task(func2()),
asyncio.create_task(func3())
]
await asyncio.wait(tasks)
if __name__ == ‘__main__’:
t1 = time.time()
asyncio.run(main())
t2 = time.time()
print(t2-t1)
- 在爬虫领域的运用
async def download(url):
print(“准备开始下载”)
await asyncio.sleep(2) # 网络请求
print(“下载完成”)
async def main():
urls = [
“http://www.baidu.com”,
“http://www.bilibili.com”,
“http://www.163.com”
]
tasks = []
for url in urls:
d = asyncio.create_task(download(url)) # 解决版本报警告问题
tasks.append(d)
await asyncio.wait(tasks)
if __name__ == ‘__main__’:
asyncio.run(main())
selenium
- 简介
能不能让我的程序连接到浏览器, 让浏览器完成各种复杂的操作, 我们只接受最终的结果
selenium:自动化测试工具
可以: 打开浏览器,然后像人一样去操作浏览器
我们可以从selenium中直接提取网页中的各种信息
- 环境搭建
环境搭建:
pip install selenium -i 清华源
下载浏览器驱动: https://npm.taobao.org/mirrors/chromedriver
把解压缩的浏览器驱动 chromedriver 放在python解释器所在的文件
让selenium启动谷歌浏览器
注意事项:
所装的驱动版本要和你所使用的浏览器版本一样
没有一样的 就找相近的
- 运用
from selenium.webdriver import Chrome
# 1. 创建浏览器对象
web = Chrome()
# 2. 打开一个网址
web.get(“https://www.baidu.com”)
print(web.title)
- 无头浏览器
from selenium.webdriver.chrome.options import Options
# 准备好参数配置
opt = Options()
opt.add_argument(“–headless”)
opt.add_argument(“–disbate-gpu”)
web = Chrome(options=opt) # 把参数配置设置到浏览器中
: 此方法只是将打开的浏览器隐藏了, 实际后台还是打开运行的,如果selenium运行多了没关闭打开的页面,会占用很多cpu,所以记得打开终端服务器关闭
- 注意
1、浏览器路径问题
以谷歌为例,当安装路径不是默认安装路径时,需指定谷歌的安装路径
option = webdriver.ChromeOptions()
option.binary_location = ‘D:GoogleChromeApplicationchrome.exe’ # 以我的安装路径为例
web = webdriver.Chrome(chrome_options=option)
web.get(url)
神龙|纯净稳定代理IP免费测试>>>>>>>>天启|企业级代理IP免费测试>>>>>>>>IPIPGO|全球住宅代理IP免费测试