GAN简介(Generative Adversarial Nets)
小偷(Generator Network)通过随机变量(Random Vector)生成假钱(Fake Image)存进银行(Discriminator Network),银行通过真钱(Real Image)、假钱(Fake Image)学习判断小偷的假钱,循环上述步骤。
小偷希望银行判断假钱为真钱,所以将假钱(标签值为真)交给银行判断,得到银行反馈的loss,以此进行更新迭代,优化造假技术
银行希望准确判断真假币,所以同时对小偷的假钱(标签值为假)、和训练的真钱(标签值为真)进行训练,以此进行更新迭代
; 损失函数
import torch
from torch import autograd
import torch.nn as nn
import math
input = autograd.Variable(torch.tensor([
[1.9072, 1.1079, 1.4906],
[-0.6548, -0.0512, 0.7608],
[-0.0614, 0.6583, 0.1095]
]))
print(input)
print('-' * 100)
m = nn.Sigmoid()
print(m(input))
print('-' * 100)
target = torch.FloatTensor([
[0, 1, 1],
[1, 1, 1],
[0, 0, 0]
])
print(target)
print('-' * 100)
r11 = 0 * math.log(0.8707) + (1 - 0) * math.log((1 - 0.8707))
r12 = 1 * math.log(0.7517) + (1 - 1) * math.log((1 - 0.7517))
r13 = 1 * math.log(0.8162) + (1 - 1) * math.log((1 - 0.8162))
r21 = 1 * math.log(0.3419) + (1 - 1) * math.log((1 - 0.3419))
r22 = 1 * math.log(0.4872) + (1 - 1) * math.log((1 - 0.4872))
r23 = 1 * math.log(0.6815) + (1 - 1) * math.log((1 - 0.6815))
r31 = 0 * math.log(0.4847) + (1 - 0) * math.log((1 - 0.4847))
r32 = 0 * math.log(0.6589) + (1 - 0) * math.log((1 - 0.6589))
r33 = 0 * math.log(0.5273) + (1 - 0) * math.log((1 - 0.5273))
r1 = -(r11 + r12 + r13) / 3
r2 = -(r21 + r22 + r23) / 3
r3 = -(r31 + r32 + r33) / 3
bceloss = (r1 + r2 + r3) / 3
print(bceloss)
print('-' * 100)
loss = nn.BCELoss()
print(loss(m(input), target))
print('-' * 100)
loss = nn.BCEWithLogitsLoss()
print(loss(input, target))
print('-' * 100)
CycleGan
简介
- *实现效果
- *无须配对数据
- 如何学习
生成器Gab通过真斑马生成假马,假马通过Gba生成假斑马,假斑马与真斑马产生L2损失,迭代优化 - 整体网络架构
- PatchGAN
; 入门测试
- *源码地址
https://github.com/junyanz/pytorch-CycleGAN-and-pix2pix
- 数据下载
以文本形式打开文件
复制下载链接
- 训练好的参数权重
https://github.com/junyanz/pytorch-CycleGAN-and-pix2pix/blob/master/scripts/download_cyclegan_model.sh#L3
http://efrosgans.eecs.berkeley.edu/cyclegan/pretrained_models/
将下载好的horse2zebra.pth文件放到pytorch-CycleGAN-and-pix2pix-master\checkpoints\horse2zebra_pretrained下,并修改名称为latest_net_G.pth
- *启动测试
测试参数
--dataroot datasets/horse2zebra/testA
--name horse2zebra.pth_pretrained
--model test --no_dropout
--gpu_ids -1
在pytorch-CycleGAN-and-pix2pix-master\results\horse2zebra_pretrained\test_latest下保存结果
打开index.html
visdom
CycleGan训练时使用visdom作为可视化工具,训练前先启动visdom
pip install visdom
python -m visdom.server
stargan
- *何为star
- 基本思路
- 整体流程
*输入图片与编码特征,通过生成器得到假照片,再将假照片通过生成器得到真实照片,并与原图进行对比,缩小真实照片与原图的差距
stargan使用编码代替风格,特征性不强,没有参与计算
- 扩展:变声器
; stargan-v2
- 整体网络架构
- *编码器训练(Style reconstruction)
- 多样化训练(Style diversification)
- *cycle loss
代码分析
- 源码下载
https://github.com/clovaai/stargan-v2 - *导入必须的包
conda create -n stargan-v2 python=3.6.7
conda activate stargan-v2
conda install -y pytorch=1.4.0 torchvision=0.5.0 cudatoolkit=10.0 -c pytorch
conda install x264=='1!152.20180717' ffmpeg=4.0.2 -c conda-forge
pip install opencv-python==4.1.2.30 ffmpeg-python==0.2.0 scikit-image==0.16.2
pip install pillow==7.0.0 scipy==1.2.1 tqdm==4.43.0 munch==2.5.0
- *生成器
class Generator(nn.Module):
def __init__(self, img_size=256, style_dim=64, max_conv_dim=512, w_hpf=1):
super().__init__()
dim_in = 2**14 // img_size
self.img_size = img_size
self.from_rgb = nn.Conv2d(3, dim_in, 3, 1, 1)
self.encode = nn.ModuleList()
self.decode = nn.ModuleList()
self.to_rgb = nn.Sequential(
nn.InstanceNorm2d(dim_in, affine=True),
nn.LeakyReLU(0.2),
nn.Conv2d(dim_in, 3, 1, 1, 0))
repeat_num = int(np.log2(img_size)) - 4
if w_hpf > 0:
repeat_num += 1
for _ in range(repeat_num):
dim_out = min(dim_in*2, max_conv_dim)
self.encode.append(
ResBlk(dim_in, dim_out, normalize=True, downsample=True))
self.decode.insert(
0, AdainResBlk(dim_out, dim_in, style_dim,
w_hpf=w_hpf, upsample=True))
dim_in = dim_out
for _ in range(2):
self.encode.append(
ResBlk(dim_out, dim_out, normalize=True))
self.decode.insert(
0, AdainResBlk(dim_out, dim_out, style_dim, w_hpf=w_hpf))
if w_hpf > 0:
device = torch.device(
'cuda' if torch.cuda.is_available() else 'cpu')
self.hpf = HighPass(w_hpf, device)
def forward(self, x, s, masks=None):
x = self.from_rgb(x)
cache = {}
for block in self.encode:
if (masks is not None) and (x.size(2) in [32, 64, 128]):
cache[x.size(2)] = x
x = block(x)
for block in self.decode:
x = block(x, s)
if (masks is not None) and (x.size(2) in [32, 64, 128]):
mask = masks[0] if x.size(2) in [32] else masks[1]
mask = F.interpolate(mask, size=x.size(2), mode='bilinear')
x = x + self.hpf(mask * cache[x.size(2)])
return self.to_rgb(x)
归一化层,目前主要有这几个方法,Batch Normalization(2015年)、Layer Normalization(2016年)、Instance Normalization(2017年)、Group Normalization(2018年)、Switchable Normalization(2018年);
将输入的图像shape记为[N, C, H, W],这几个方法主要的区别就是在,
- batchNorm是在batch上,对NHW做归一化,对小batchsize效果不好;
- layerNorm在通道方向上,对CHW归一化,主要对RNN作用明显;
- instanceNorm在图像像素上,对HW做归一化,用在风格化迁移;
- GroupNorm将channel分组,然后再做归一化;
- *SwitchableNorm是将BN、LN、IN结合,赋予权重,让网络自己去学习归一化层应该使用什么方法。
- *风格特征编码
class MappingNetwork(nn.Module):
def __init__(self, latent_dim=16, style_dim=64, num_domains=2):
super().__init__()
layers = []
layers += [nn.Linear(latent_dim, 512)]
layers += [nn.ReLU()]
for _ in range(3):
layers += [nn.Linear(512, 512)]
layers += [nn.ReLU()]
self.shared = nn.Sequential(*layers)
self.unshared = nn.ModuleList()
for _ in range(num_domains):
self.unshared += [nn.Sequential(nn.Linear(512, 512),
nn.ReLU(),
nn.Linear(512, 512),
nn.ReLU(),
nn.Linear(512, 512),
nn.ReLU(),
nn.Linear(512, style_dim))]
def forward(self, z, y):
h = self.shared(z)
out = []
for layer in self.unshared:
out += [layer(h)]
out = torch.stack(out, dim=1)
idx = torch.LongTensor(range(y.size(0))).to(y.device)
s = out[idx, y]
return s
- *判别器
class Discriminator(nn.Module):
def __init__(self, img_size=256, num_domains=2, max_conv_dim=512):
super().__init__()
dim_in = 2**14 // img_size
blocks = []
blocks += [nn.Conv2d(3, dim_in, 3, 1, 1)]
repeat_num = int(np.log2(img_size)) - 2
for _ in range(repeat_num):
dim_out = min(dim_in*2, max_conv_dim)
blocks += [ResBlk(dim_in, dim_out, downsample=True)]
dim_in = dim_out
blocks += [nn.LeakyReLU(0.2)]
blocks += [nn.Conv2d(dim_out, dim_out, 4, 1, 0)]
blocks += [nn.LeakyReLU(0.2)]
blocks += [nn.Conv2d(dim_out, num_domains, 1, 1, 0)]
self.main = nn.Sequential(*blocks)
def forward(self, x, y):
out = self.main(x)
out = out.view(out.size(0), -1)
idx = torch.LongTensor(range(y.size(0))).to(y.device)
out = out[idx, y]
return out
stargan-vc2
http://www.kecl.ntt.co.jp/people/kaneko.takuhiro/projects/stargan-vc2/index.html
- *变声器
- 输入数据
- 预处理
- 特征汇总
- MFCC
- 生成器
- 语言数据包含的成分
- Instance Normalization 和 Adaptive Instance Normalization
- Instance Normalization
内容编码器只需要内容,不需要语言特征,所以使用Instance Normalization对每个特征图进行归一化,将声音特征平均化,去掉语言特性 - AdaIn
In归一化去掉了语言特征,AdaIn则是通过额外的FC层赋予语言特征 - PixelShuffle
上采样与下采样:都是老路子,stride=2来下采样,反卷积来上采样
**PixelShuffle层又名亚像素卷积层,是论文Real-Time Single Image and Video Super-Resolution Using an Efficient Sub-Pixel Convolutional Neural Network中介绍的一种应用于超分辨率重建应用的具有上采样功能的卷积层。这篇ESPCN论文介绍了这种层的功能,sub-pixel convolution layer以stride = 1 r stride=\frac{1}{r}stride= r1 (r rr为SR的放大倍数upscaling factor)去提取feature map,虽然称之为卷积,但是其并没用用到任何需要学习的参数,它的原理也很简单,就是将输入feature map进行像素重组,也就是说亚像素卷积层虽用卷积之名,但却没有做任何乘加计算,只是用了另一种方式去提取特征罢了:
*
如上图所示的最后一层就是亚像素卷积层,它就是将输入格式为( b a t c h , r 2 C , H , W ) (batch,r^2C, H, W)(batch,r 2C,H,W)的feature map中同一通道的像素提取出来作为输出feature map的一小块,遍历整个输入feature map就可以得到最后的输出图像。整体来看,就好像是用1r\frac{1}{r}r1的步长去做卷积一样,这样就造成了不是对整像素点做卷积,而是对亚像素做卷积,故称之为亚像素卷积层,最后的输出格式就是( b a t c h , 1 , r H , r W ) (batch,1, rH,rW)(batch,1,rH,rW)。
因此,简单一句话,PixelShuffle层做的事情就是将输入feature map像素重组输出高分辨率的feature map,是一种上采样方法,具体表达为
其中r为上采样倍率(上图中r = 3)
- 判别器
; 图像超分辨率重构(SPGAN)
- *网络架构
- *基本思路
基本的GAN网络思想,其中生成器使用了PixelShuffle实现超分辨率重建,同时为了提升细节效果,引入vgg19,将生成器生成的假图和真图放入vgg19模型提取特征,并提取最后一层特征图进行损失计算,将该损失加入到生成器损失
- *工具
图像补全
论文:Globally and Locally Consistent Image Completion
- 网络架构
- 全卷积网络,不限制输入图片大小
- Dilated Conv 空洞卷积 增大感受野 替代pooling
- Local Discriminator 局部判别网络 收集局部信息
- Global Discriminator 全局判别网络 收集全局信息
- 图像生成网络
- 最后的合成网络
- MSE损失
通过生成图像与原图的MSE损失,避免过度依赖判别器的特征判断 - 分步计算损失
前Tc次迭代只计算MSE损失,当t大于TC小于Tc+Td时计算判别器损失,当t大于Tc+Td时计算MSE和判别器损失
Original: https://blog.csdn.net/weixin_50973728/article/details/125513750
Author: C--G
Title: 1、生成对抗网络入门
相关阅读1
Title: 数字信号音频采集及时域频域加噪设计滤波器处理项目入门
项目名称:信号时频域分析和滤波
摘要:本项目借助MATLAB软件,对语音连续时间信号进行采集、时域和频域分析,对加噪后的语音信号进行时域和频域分析,分析并设计了FIR和IIR滤波器进行语音滤波处理。通过对语音信号进行采样得到时域波形,通过对采样得到的数据进行FFT变换得到频域波形,利用冲激响应不变法或双线性变换法设计IIR滤波器,利用窗函数法设计FIR滤波器。在滤波器设计后,利用低通滤波器,对加噪后的语音信号进行滤波处理。通过仿真,观察滤波前后语音信号时域和频域波形图,可知得到了合适的滤波器参数和较好的滤波效果。
关键词:采样;FFT;滤波;
1. 一维连续时间信号采集和分析
1.1 信号的时域分析
(1)采集的信号是连续一维时间信号,例如语音信号等;
(2)画出所采集到的一维信号的时域波形。一维连续时间信号首先需要对其进行采样;绘制出采集信号的时域波形。
首先采集语音信号并命名为'data1.wav',取其中30点进行处理,画出语音信号的时域波形及以1为采样间隔进行采样后的采样波形图如图1所示。程序代码见附录1中程序一和程序二所示。
图1 信号的时域波形以及以1为采样间隔的采样波形图
1.2 信号的 频域分析
1 .2.1 计算并画出信号的DTFT幅值谱结果波形
(1)首先研究改变w的取值范围对DTFT幅度响应的影响,共分为两种情况。第一,步长取0.01 π时,w 取0到2π。第二:步长取0.01 π时,w 取-π到π。分别计算的DTFT 幅值谱如图2 所示,其运行代码见附录1程序三所示。
图2 改变 _w_范围后的DTFT幅值谱图
通过观察图2可以看出,w 取0到2π与取-π到π时的区别在于,当取0到2π时,在0 到π/2 和3 π/2 到2 π间幅度较大,π/2 到3 π/2 之间幅度较小;当取-π到π时,在-π/2 到0和0 到π/2 间幅度较大,-π到-π/2 和π/2 到π间幅度较小;可以看出π到2 π间波形可以由-π到0 间波形搬移得到,即π到2 π间波形和-π到0 间波形相同。
(2)然后研究步长对结果的影响,这里控制w的取值为0-2 π,步长分为两种情况。第一,步长为0.001 π时的DTFT幅值谱图。第二,步长为0.1 π时的DTFT幅值谱图。运行结果如图3 所示,程序见附件1程序四所示。
图3 改变步长 d _w_后的DTFT幅值谱图
经过多次改变步长,由图3可知,当步长过大时,呈现出的幅频响应由于采样点过少出现了失真,无法表征DTFT的具体细节,当步长过小时,图案没有发生明显变化,与语音信号原时域波形相近,最终判断在0.01 π附近效果最好。
1 .2.2计算并画出不同点数的DFT结果波形
① 增加采样点,增加数据长度;
这种情况改变了原始序列,也就是对应长序列的情况,就不存在近似不足的情况,所以重点采用下面方法解决问题。
② 补零增加数据长度
这种情况未改变原始序列,只是补零增加序列的长度,使得在单位圆上的采样点增多,这样得到的DFT谱线就更加精细,其包络就越接近DTFT的结果,这样就可以利用DFT计算DTFT。
未增加取样点并且未补零之前的运行结果如图8所示,代码见附录1程序六所示。
图8 未增加取样点并且未补零的30点DFT幅频特征
情况一:增加取样点,这里取取样点为6 0点,运行结果如下图9所示,代码见附录1程序七所示。
图9 增加取样点为6 0点的DFT幅频特征
通过观察图9可知,当采样频率不变,取样点增加后,时间记录长度增大,提高了频率分辨率,改变了原始波形,信号强度改变。
情况二:补零,这里补零到100点,运行结果如下图10所示。代码见附录1程序八所示。
图10 补零后的DFT幅频特征
通过观察图10波形分析得出,与图8 进行对比可以看出,随着补零点数的增加,采样点越来越密集,使频域抽样更密,减小了栅栏效应,可以更好的还原原始波形。
2. 加 噪信号 的时频域 分析
2.1 噪声 信频域 分析
主要选用正弦信号噪声和高斯白噪声两类噪声(加性)进行分析,对这两类噪声信号进行介绍,画出噪声信号的时域和频域波形,观察分析噪声信号的时域和频域特点。
注意:不限于这两类噪声。
2.1. 1 正弦信号噪声
2.1. 2 高斯白噪声
2.2 加噪信号的时域和频域分析
具体要求:分别选一段规则信号(例如正弦信号)和语音信号添加噪声(加性);画出添加噪声后信号的时域、频域波形,对其进行分析。
2.2.1规则信号的加噪分析
2.2.2语音信号加噪处理
3 信号滤波分析
3.1 滤波器设计 原理
3.1.1 IIR滤波器设计
IIR滤波器的设计可选用巴特沃斯或切比雪夫进行设计,可以随意选择冲激响应不变法或双线性变换法进行模拟滤波器到数字滤波器的转换。
3.1.2 FIR滤波器设计
利用窗函数法设计能够滤出噪声的FIR低通滤波器。
3.2 信号滤波分析
(1)添加噪声的信号滤波分析
选用3.1节中的一种滤波器设计方式,根据对2.2节中添加噪声后信号的频谱进行频域分析,确定低通滤波器的通带、阻带截止频率、通带最大衰减和阻带最小衰减等技术指标(可选几组合适的指标进行实验),自行设计满足技术指标的低通滤波器,画出滤波器的幅度谱,对比滤波前后信号的时域及频域波形,分别从主观和客观上评价滤波效果,得出结论,其中客观评价标准请查阅资料自行确定(例如信噪比等)。
因为该报告太长了,在第二部分和第三部分只是列出大纲和要求,如果大家需要完整报告,可以参考下面的链接。
完整报告
数字信号音频采集及时域频域加噪设计滤波器处理项目菜鸟完整报告.docx-专业指导文档类资源-CSDN文库
完整代码
数字信号音频采集及时域频域加噪设计滤波器处理项目菜鸟入门代码.zip-专业指导文档类资源-CSDN文库
Original: https://blog.csdn.net/qq_51940383/article/details/122510772
Author: 小王yue
Title: 数字信号音频采集及时域频域加噪设计滤波器处理项目入门
相关阅读2
Title: 【简单明了】anaconda 安装 jupyter 创建 tensorflow-gpu环境,深度学习模型训练用gpu跑,jupyter和pycharm上运行成功
相信学深度学习的童鞋们,都遇到了非常棘手的问题!就是训练模型用的cpu而不是gpu!而gpu是专门用来计算的,不拿来用,岂不是浪费?而网上的教程要装cudo 又要下 cudnn ,折磨了我一两天还没弄好,终于在机缘巧合之下,成功了!!!现在教大家如何简单地让模型在gpu上跑起来:
安装前骤:大家先更新一下自己显卡驱动
https://www.nvidia.cn/Download/index.aspx?lang=cn
找到自己对应的最新显卡驱动,然后下载,安装。
1、然后需要自行再装好anaconda(都搜到在下这个教程了,应该都已经装好这个了吧)
2、安装好后, 创建清华镜像链接
安装好anaonda后,点击开始菜单进入"Anaconda Navigator"环境管理页面
依次点击左边导航窗口的"Environments"-"baset(root)(播放键)"-"Open Terminal"进入命令行模式,使用conda命令依次执行下面三条命令:
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
回车
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/
回车
conda config --set show_channel_urls yes
回车
3、创建tensorflow虚拟环境
3、等右下角进度条好了,进入该虚拟环境的 open terminal
4、安装相应的 python 模块包
接下来,依次点击"tensorflow_new"-"Open Terminal"进入命令行模式:
使用以下命令安装相应的python模块包(使用pip命令):
pip install numpy matplotlib Pillow scikit-learn pandas -i https://pypi.tuna.tsinghua.edu.cn/simple
(注意其中的Pillow的P为大写字母)
5、 安装最新 tensorflow、tensorflow-gpu(默认安装最新)
模块包安装完成后,在的该命令窗口下,使用如下命令安装tensorflow最新版:
pip install tensorflow -i https://pypi.tuna.tsinghua.edu.cn/simple
务必多等一会,安装成功后接着安 tensorflow-gpu最新版
pip install tensorflow-gpu -i https://pypi.tuna.tsinghua.edu.cn/simple
(安了最新的童鞋下面两行代码可忽略)其他版本可参照下列代码输入版本号,当然像我这样追求完美的人肯定用最新版啦!注:其他版本博主我死活不能在gpu上跑,尽量装最新的吧,已经累了
pip install tensorflow==2.4.1 -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install tensorflow-gpu==2.4.1 -i https://pypi.tuna.tsinghua.edu.cn/simple
6、 测试 tensorflow_new 是否安装成功
接着在这个命令窗口输入 ,可查看到全部库的信息,看是否找到tensorflow ,tensorflow-gpu
pip list #库查询
"Anaconda Navigator"中,依次点击"tensorflow_new"-"Open With Python" ,进入 python 环境并输入:
import tensorflow as tf 回车
不出错即安装成功。也可继续输入以下命令查看 tensorflow 版本:
tf.version
相信童鞋们不用多久到这一步,接着干!
不要网上的对应什么什么版本,头秃。直接先下好cudo,安装。直接就在anaconda里面装cudnn,点小框框,再点击apply 进行安装,信我,无敌!
https://developer.nvidia.com/cuda-toolkit-archive
自定义,勾上第一个勾,有visual studio 的把visual studio 的勾取消掉,不然插件冲突会报错。
然后进入tensorflow_new 新环境 安装cudnn
有些anaconda安装库的时候会报错,清一下缓存包可解决部分报错,我觉得主要还是看缘分。
接下来安装该环境下的jupyter
拖到桌面,修改工作路径,详情转下面链接 记得顺手点个赞哈
https://blog.csdn.net/qq_48562084/article/details/118969139?spm=1001.2014.3001.5502
先别打开,继续"tensorflow_new"-"Open Terminal"进入命令行模式,我们要为jupyter里面添加 刚创建的虚拟环境,输入以下代码
python -m ipykernel install --user --name=tensorflow_new #name=环境名
关闭命令窗口,在桌面打开更改过路径的jupyter,new 一个工作
选择tensorflow_new 输入以下代码
import tensorflow as tf
import numpy as np
import os
import matplotlib.pyplot as plt
print("TensorFlow version is :",tf.__version__)
print("Keras version is :",tf.keras.__version__)
print("GPU is","available" if tf.test.is_gpu_available()else "NOT AVAILABLE")
如出现这个,就说明
成功啦!创作不意,每一个点赞评论收藏都是对我的莫大鼓励!谢谢大家!
Original: https://blog.csdn.net/qq_48562084/article/details/119054757
Author: 定个小目标 不胖2斤不改名
Title: 【简单明了】anaconda 安装 jupyter 创建 tensorflow-gpu环境,深度学习模型训练用gpu跑,jupyter和pycharm上运行成功
相关阅读3
Title: 使用python的requests爬取原神观测枢的内容
本文进行两个任务。
- 爬取米游社观测枢的圣遗物信息,存到本地json文件
- 爬取米游社观测枢的书籍信息及其超链接所链接的书籍内容,存到本地json文件
使用技术:Python的requests库和lxml库,用xpath语法解析html文档。
一、 爬取圣遗物信息
目标网址:https://bbs.mihoyo.com/ys/obc/channel/map/189/218?bbs_presentation_style=no_header
目标如图:
1. 每个圣遗物的标题都在div里面,class属性为"relic-describe__top–title"
2. 每个圣遗物的套装效果的div的class属性为"relic-describe__footer–list",其中该节点下面有两个div分别是两件套效果和四件套效果。
代码1 :获取页面的HTML文档
# -*- coding: utf-8 -*-
# @Author : XX
# @Time : XX
import requests
from lxml import etree
import json
import time
import random
# 爬虫之前千万记得先关掉系统代理
# 获取HTML文档
def getHtml(target_url):
try:
response = requests.get(url=target_url)
response.encoding = 'utf_8'
return etree.HTML(response.text)
except Exception as e:
print("FAIL...")
print(e)
exit(-1)
代码2 爬取圣遗物信息,存储形式为json文件,内容为一个列表,存放对象字典,逐行解读详见代码注释。
# lxml库,用xpath语法解析html
def get_artifact_list(html):
artis = [] # 圣遗物(artifact)
# 对输入的页面文档解析,获取所有标题,所有class属性为xx的div标签的内容文本
names = html.xpath('//div[@class="relic-describe__top--title"]/text()')
# div[1]是两件套效果,div[2]为四件套效果
# xpath语法里面,列表的下标从1开始
# 不直接获取text()文本,因为div[1]标签下面不仅有标签也有文本
piece2s = html.xpath('//div[@class="relic-describe__footer--list"]/div[1]')
piece4s = html.xpath('//div[@class="relic-describe__footer--list"]/div[2]')
# .xpath('string(.)')表示获取该节点下面的所有文本内容,无视下面的标签
# 例如"""二件套:攻击力提高18%。"""会得到"二件套:攻击力提高18%。"
# 逐个在列表里加入一个个目标对象字典,
for name, piece2, piece4 in zip(names, piece2s, piece4s):
artis.append({'name': name, 'piece2': piece2.xpath('string(.)'), 'piece4': piece4.xpath('string(.)')})
# 把列表写入本地json文件,使用json.dumps(obj, )写入对象
with open("artifacts.json", 'w', encoding='utf_8') as fp:
# 必须令ensure_ascii=False,否则输出内容的中文的编码形式不可读,是\u的ascii形式
fp.write(json.dumps(artis, ensure_ascii=False))
print("----end----")
if __name__ == '__main__':
artifact_url = "https://bbs.mihoyo.com/ys/obc/channel/map/189/218?bbs_presentation_style=no_header"
get_artifact_list(getHtml(artifact_url))
二、 爬取书籍
目标网址:https://bbs.mihoyo.com/ys/obc/channel/map/189/68?bbs_presentation_style=no_header
首先获取每一本书的内容的超链接。
然后再获取该超链接的内容,来爬取该书籍的具体信息和内容。
进入超链接,就是书本的详细内容了。大致看一下每一个书的信息与内容所在的节点。书籍信息就是阴影部分下面两个节点中,第一个div包括 [名字、游戏内的获取方式、概述、作者],第二个div是书籍的内容。信息和内容所在div标签,在HTML文档中是并列的关系。
代码3 :获取某一本书的内容和信息
该函数输入某一本书的超链接,返回一个列表,返回列表而不是字典原因如上图,某一本书可能有多部,尘游记一、尘游记二、尘游记三等等。每一本书是一个字典,存【名字、获取方式、简述、作者、内容】
def get_article(target_url):
article_html = getHtml(target_url)
blocks = article_html.xpath('//div[@class="obc-tmpl obc-tmpl--col-l2r1"]')
name_list = ['name', 'obtained', 'abstract', 'author']
data = []
res = {}
for i, block in zip(range(len(blocks)), blocks):
res = {}
infos = block.xpath('./div[1]/div/table/tbody/tr')
for j, info in zip(range(4), infos):
if j == 0:
# pass
res[name_list[j]] = info.xpath('./td/text()')
else:
res[name_list[j]] = info.xpath('./td/p/text()')
content = block.xpath('./div[2]/div/div[2]/p')
res_str = ""
for line in content:
line_str = line.xpath('./text()')
if len(line_str) > 0:
res_str += line_str[0]+"\n"
# print(res)
res["content"] = res_str
res["linkurl"] = target_url
data.append(res)
# break
print('----end----')
return data
# 爬取每一本书
def get_book_list(html):
books = []
elems = html.xpath('//ul[@class="position-list__list position-list__list--default"]')[0]
# 每一本书的两个信息,书名和超链接。
book_names = elems.xpath('./li/a/span/text()')
link_urls = elems.xpath('./li/a/@href')
for book_name, link_url in zip(book_names, link_urls):
# books.append({'bookname': book_name, 'linkurl': "https://bbs.mihoyo.com"+link_url}|)
# 列表的合并用+运算符即可
books += get_article("https://bbs.mihoyo.com"+link_url)
# 控制爬虫频率不要太快
print('get: ', book_name, "。停止五秒...")
time.sleep(random.random()*5)
# 爬虫结果写入json文件。
with open("genshin_books.json", 'w', encoding='utf_8') as fp:
# 比如令ensure_ascii=False,否则输出中文的编码不正确,是\u的ascii形式
fp.write(json.dumps(books, ensure_ascii=False))
print("----end----")
if __name__ == '__main__':
books_url = "https://bbs.mihoyo.com/ys/obc/channel/map/189/68?bbs_presentation_style=no_header"
get_book_list(getHtml(books_url))
结束
Original: https://www.cnblogs.com/zhaoke271828/p/16586892.html
Author: Viktor_Cullen
Title: 使用python的requests爬取原神观测枢的内容