<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>python &#8211; ChaBug安全</title>
	<atom:link href="/tags/python/feed" rel="self" type="application/rss+xml" />
	<link>/</link>
	<description>一个分享知识、结识伙伴、资源共享的博客</description>
	<lastBuildDate>Tue, 30 Jul 2019 01:59:52 +0000</lastBuildDate>
	<language>zh-CN</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=5.5.5</generator>
	<item>
		<title>使用powershell导出剪切板图片</title>
		<link>/tools/681.html</link>
		
		<dc:creator><![CDATA[Y4er]]></dc:creator>
		<pubDate>Tue, 30 Jul 2019 01:51:16 +0000</pubDate>
				<category><![CDATA[工具分享]]></category>
		<category><![CDATA[编程学习]]></category>
		<category><![CDATA[powershell]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[图床]]></category>
		<guid isPermaLink="false">/?p=681</guid>

					<description><![CDATA[怎么导出QQ截图的图片到指定位置呢？powershell来帮你 我是一个喜欢记笔记写文章的菜鸡，而使用markdown记笔记最蛋疼的就是图片的存储问题，刚开始使用的是PicGo，可...]]></description>
										<content:encoded><![CDATA[<p>怎么导出QQ截图的图片到指定位置呢？<span class="wpcom_tag_link"><a href="/tags/powershell" title="powershell" target="_blank">powershell</a></span>来帮你</p>
<p>我是一个喜欢记笔记写文章的菜鸡，而使用markdown记笔记最蛋疼的就是图片的存储问题，刚开始使用的是<a href="https://github.com/Molunerfinn/PicGo">PicGo</a>，可以直接截图然后粘贴就是markdown的图片语法，但是使用的是第三方的<span class="wpcom_tag_link"><a href="/tags/%e5%9b%be%e5%ba%8a" title="图床" target="_blank">图床</a></span>。</p>
<p>而我自己原来用第三方图床也就是新浪的图床，后来新浪一波防盗链把我搞得<del>骂骂咧咧</del>措手不及，想了想，图片还是掌握在自己手中比较好，于是就有了本文。</p>
<h1>借助PicGo搞插件？</h1>
<p>刚好自己搭了一个图床http://static.chabug.org/ ，想着参考PicGo的思路，自己写一个插件，然后实现截图 快捷键 粘贴 一套操作，岂不是美滋滋？后来看到了PicGo需要装nodejs才能用插件，再想想nodejs的依赖和蛇皮语法，直接实力劝退，不了了之。</p>
<h1><span class="wpcom_tag_link"><a href="/tags/python" title="python" target="_blank">python</a></span>自己造轮子</h1>
<p>国光师傅写过一篇<a href="https://www.sqlsec.com/2018/06/img.html">Python 编写一个免费简单的图床上传工具二</a>，但是编写思路是采用<code>xclip</code>来操作<code>ubuntu</code>下的剪切板，而苦逼windows党不配这样操作。随卒。</p>
<h1>参考PicGo自己撸</h1>
<p>研究到这一步，实际上最关键的问题在于win下怎么去导出剪切板中的图片。百度谷歌了很多文章，发现都是牛头不照马尾，在此过程中我把PicGo作者的博客翻烂了，发现PicGo作者获取剪切板的图片采用的是命令行调用 https://github.com/PicGo/PicGo-Core/blob/dev/src/utils/clipboard/windows10.ps1 这个脚本。在第一行定义了最关键的项目https://github.com/octan3/img-clipboard-dump。这个就是我们想要的东西！</p>
<p>那么我们的问题就解决了！</p>
<p>看下<strong>dump-clipboard-png.ps1</strong></p>
<pre><code class="language-powershell ">Add-Type -Assembly PresentationCore
$img = [Windows.Clipboard]::GetImage()
if ($img -eq $null) {
    Write-Host "Clipboard contains no image."
    Exit
}

$fcb = new-object Windows.Media.Imaging.FormatConvertedBitmap($img, [Windows.Media.PixelFormats]::Rgb24, $null, 0)
$file = "{0}\clipboard-{1}.png" -f [Environment]::GetFolderPath('MyPictures'),((Get-Date -f s) -replace '[-T:]','')
Write-Host ("`n Found picture. {0}x{1} pixel. Saving to {2}`n" -f $img.PixelWidth, $img.PixelHeight, $file)

$stream = [IO.File]::Open($file, "OpenOrCreate")
$encoder = New-Object Windows.Media.Imaging.PngBitmapEncoder
$encoder.Frames.Add([Windows.Media.Imaging.BitmapFrame]::Create($fcb))
$encoder.Save($stream)
$stream.Dispose()

&amp; explorer.exe /select,$file
</code></pre>
<p>首先获取剪切板的图片，如果没图片就exit，然后新建一个位图对象，新建一个file变量当作文件名，从环境变量中拿到MyPictures的路径，然后写入图片。</p>
<p>相对我们想实现的效果还差一步就是直接向剪切板写入markdown格式的图片链接。我在这放出来我修改之后的脚本。(注意修改路径)</p>
<pre><code class="language-powershell ">Add-Type -Assembly PresentationCore
$img = [Windows.Clipboard]::GetImage()
if ($img -eq $null) {
    Write-Host "Clipboard contains no image."
    Exit
}

$fcb = new-object Windows.Media.Imaging.FormatConvertedBitmap($img, [Windows.Media.PixelFormats]::Rgb24, $null, 0)
$filename = ((Get-Date -f s) -replace '[-T:]','')
$file = "E:/work/myblog/static/img/uploads/{0}.png" -f $filename
Write-Host ("`n Found picture. {0}x{1} pixel. Saving to {2}`n" -f $img.PixelWidth, $img.PixelHeight, $file)

$stream = [IO.File]::Open($file, "OpenOrCreate")
$encoder = New-Object Windows.Media.Imaging.PngBitmapEncoder
$encoder.Frames.Add([Windows.Media.Imaging.BitmapFrame]::Create($fcb))
$encoder.Save($stream)
$stream.Dispose()

$str =  "![{0}](/img/uploads/{1}.png)" -f $filename,$filename
[Windows.Clipboard]::SetText($str)
</code></pre>
<p>然后把<code>dump-clipboard-png.cmd</code>改名为<code>png.cmd</code>和<code>png.ps1</code>放到环境变量里，截图，cmd运行<code>png</code>，那么你的剪切板就会写入一个markdown格式的图片咯。并且图片保存在了你的本地。</p>
<h1>进一步操作</h1>
<p>到现在我们基本的效果已经实现了，不过还是差一点，怎么去实现按下快捷键就导出图片到我们指定的位置呢？参考国光师傅的代码已经写的很清楚了。</p>
<p>https://github.com/sqlsec/imageMD/blob/master/imageMD.py</p>
<p><strong>文笔垃圾，措辞轻浮，内容浅显，操作生疏。不足之处欢迎大师傅们指点和纠正，感激不尽。</strong></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Python模块学习之Logging日志模块</title>
		<link>/code/640.html</link>
		
		<dc:creator><![CDATA[Y4er]]></dc:creator>
		<pubDate>Sun, 13 Jan 2019 07:04:57 +0000</pubDate>
				<category><![CDATA[编程学习]]></category>
		<category><![CDATA[logging]]></category>
		<category><![CDATA[python]]></category>
		<guid isPermaLink="false">/?p=640</guid>

					<description><![CDATA[最近一直想自己的批量框架，参考了POC-T框架和sqlmap的框架结构，发现logging模块被大量用来处理控制台输出以及日志记录，鉴于我自己也要写框架，那么本文就记录下我的log...]]></description>
										<content:encoded><![CDATA[<p class="md-end-block" contenteditable="true"><span class="">最近一直想自己的批量框架，参考了POC-T框架和sqlmap的框架结构，发现<span class="wpcom_tag_link"><a href="/tags/logging" title="logging" target="_blank">logging</a></span>模块被大量用来处理控制台输出以及日志记录，鉴于我自己也要写框架，那么本文就记录下我的logging模块学习记录。</span></p>
<h1 class="md-end-block md-heading" contenteditable="true"><span class="">为什么需要logging</span></h1>
<p class="md-end-block" contenteditable="true"><span class="">在开发过程中，如果程序出现了问题，我们可以使用编辑器的Debug模式来检查bug，但是在发布之后，我们的程序相当于在一个黑盒状态去运行，我们只能看到运行效果，可是程序难免出错，这种情况的话我们就需要日志模块来记录程序当前状态、时间状态、错误状态、标准输出等，这样不论是正常运行还是出现报错，都有记录，我们可以针对性的快速排查问题。</span></p>
<p class="md-end-block" contenteditable="true">因此，日志记录对于程序的运行状态以及debug都起到了很高效的作用。如果一个程序没有标准的日志记录，就不能算作一个合格的开发者。</p>
<h1 class="md-end-block md-heading" contenteditable="true">logging和print的对比</h1>
<ul class="ul-list" data-mark="-">
<li class="md-list-item">
<p class="md-end-block" contenteditable="true"><span class="">logging对输出进行了分级，print没有</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block" contenteditable="true">logging具有更灵活的格式化功能，比如运行时间、模块信息</p>
</li>
<li class="md-list-item">
<p class="md-end-block" contenteditable="true">print输出都在控制台上，logging可以输出到任何位置，比如文件甚至是远程服务器</p>
</li>
</ul>
<h1 class="md-end-block md-heading" contenteditable="true">logging的结构拆分</h1>
<figure class="md-table-fig" contenteditable="false">
<table class="md-table">
<thead>
<tr class="md-end-block">
<th><span class="td-span" contenteditable="true">模块</span></th>
<th><span class="td-span" contenteditable="true">用途</span></th>
</tr>
</thead>
<tbody>
<tr class="md-end-block">
<td><span class="td-span" contenteditable="true">Logger</span></td>
<td><span class="td-span" contenteditable="true">记录日志时创建的对象，调用其方法来传入日志模板和信息生成日志记录</span></td>
</tr>
<tr class="md-end-block">
<td><span class="td-span" contenteditable="true">Log Record</span></td>
<td><span class="td-span" contenteditable="true">Logger对象生成的一条条记录</span></td>
</tr>
<tr class="md-end-block">
<td><span class="td-span" contenteditable="true">Handler</span></td>
<td><span class="td-span" contenteditable="true">处理日志记录，输出或者存储日志记录</span></td>
</tr>
<tr class="md-end-block">
<td><span class="td-span" contenteditable="true">Formatter</span></td>
<td><span class="td-span" contenteditable="true">格式化日志记录</span></td>
</tr>
<tr class="md-end-block">
<td><span class="td-span" contenteditable="true">Filter</span></td>
<td><span class="td-span" contenteditable="true">日志过滤器</span></td>
</tr>
<tr class="md-end-block">
<td><span class="td-span" contenteditable="true">Parent Handler</span></td>
<td><span class="td-span" contenteditable="true">Handler之间存在分层关系</span></td>
</tr>
</tbody>
</table>
</figure>
<h1 class="md-end-block md-heading" contenteditable="true">简单的实例</h1>
<pre class="lang:default decode:true md-fences md-end-block ty-contain-cm modeLoaded">import logging
​
logger = logging.getLogger("Your Logger")
logger.setLevel(logging.DEBUG)
handler = logging.StreamHandler()
formatter = logging.Formatter(fmt='%(asctime)s - %(name)s - %(levelname)s - %(message)s', datefmt='%Y/%m/%d %H:%M:%S')
handler.setFormatter(formatter)
logger.addHandler(handler)
​
logger.info("this is info msg")
logger.debug("this is debug msg")
logger.warning("this is warn msg")
logger.error("this is error msg")</pre>
<p class="md-end-block" contenteditable="true">输出</p>
<pre class="lang:default decode:true md-fences md-end-block ty-contain-cm modeLoaded">2019/01/13 13:21:17 - Your Logger - INFO - this is info msg
2019/01/13 13:21:17 - Your Logger - DEBUG - this is debug msg
2019/01/13 13:21:17 - Your Logger - WARNING - this is warn msg
2019/01/13 13:21:17 - Your Logger - ERROR - this is error msg</pre>
<p class="md-end-block" contenteditable="true">我们来理解下这个实例。</p>
<p class="md-end-block" contenteditable="true">首先创建了一个<span spellcheck="false"><code>logger</code></span>对象作为生成日志记录的对象，然后设置输出级别为<span spellcheck="false"><code>DEBUG</code></span>，然后创建了一个<span spellcheck="false"><code>StreamHandler</code></span>对象<span spellcheck="false"><code>handler</code></span>，来处理日志，随后创建了一个<span spellcheck="false"><code>formatter</code></span>对象来格式化输出日志记录，然后把<span spellcheck="false"><code>formatter</code></span>赋给<span spellcheck="false"><code>handler</code></span>，最后把<span spellcheck="false"><code>handler</code></span>处理器添加到我们的<span spellcheck="false"><code>logger</code></span>对象中，完成了整个处理流程。</p>
<p class="md-end-block" contenteditable="true">知道整个流程之后我们来看一些细的东西。</p>
<h2 class="md-end-block md-heading" contenteditable="true">Level</h2>
<p class="md-end-block" contenteditable="true"><span class="" spellcheck="false"><code>logging</code></span>模块中自带了几个日志级别</p>
<figure class="md-table-fig" contenteditable="false">
<table class="md-table">
<thead>
<tr class="md-end-block">
<th><span class="td-span" contenteditable="true">等级</span></th>
<th><span class="td-span" contenteditable="true">数值</span></th>
<th><span class="td-span" contenteditable="true">对应方法</span></th>
</tr>
</thead>
<tbody>
<tr class="md-end-block">
<td><span class="td-span" contenteditable="true">CRITICAL</span></td>
<td><span class="td-span" contenteditable="true">50</span></td>
<td><span class="td-span" contenteditable="true">logger.critical(&#8220;msg&#8221;)</span></td>
</tr>
<tr class="md-end-block">
<td><span class="td-span" contenteditable="true">FATAL</span></td>
<td><span class="td-span" contenteditable="true">50</span></td>
<td><span class="td-span" contenteditable="true">logger.fatal(&#8220;msg&#8221;)</span></td>
</tr>
<tr class="md-end-block">
<td><span class="td-span" contenteditable="true">ERROR</span></td>
<td><span class="td-span" contenteditable="true">40</span></td>
<td><span class="td-span" contenteditable="true">logger.error(&#8220;msg&#8221;)</span></td>
</tr>
<tr class="md-end-block">
<td><span class="td-span" contenteditable="true">WARNING</span></td>
<td><span class="td-span" contenteditable="true">30</span></td>
<td><span class="td-span" contenteditable="true">logger.warning(&#8220;msg&#8221;)</span></td>
</tr>
<tr class="md-end-block">
<td><span class="td-span" contenteditable="true">WARN</span></td>
<td><span class="td-span" contenteditable="true">30</span></td>
<td><span class="td-span" contenteditable="true"><del>logger.warn(&#8220;msg&#8221;)</del>废弃</span></td>
</tr>
<tr class="md-end-block">
<td><span class="td-span" contenteditable="true">INFO</span></td>
<td><span class="td-span" contenteditable="true">20</span></td>
<td><span class="td-span" contenteditable="true">logger.info(&#8220;msg&#8221;)</span></td>
</tr>
<tr class="md-end-block">
<td><span class="td-span" contenteditable="true">DEBUG</span></td>
<td><span class="td-span" contenteditable="true">10</span></td>
<td><span class="td-span" contenteditable="true">logger.debug(&#8220;msg&#8221;)</span></td>
</tr>
<tr class="md-end-block">
<td><span class="td-span" contenteditable="true">NOTSET</span></td>
<td><span class="td-span" contenteditable="true">0</span></td>
<td><span class="td-span" contenteditable="true">无</span></td>
</tr>
</tbody>
</table>
</figure>
<p class="md-end-block" contenteditable="true">在我们的实例中我们设置了输出级别为<span class="" spellcheck="false"><code>DEBUG</code></span></p>
<pre class="lang:default decode:true md-fences md-end-block ty-contain-cm modeLoaded">logger.setLevel(logging.DEBUG)</pre>
<p class="md-end-block" contenteditable="true">那么在<span class="" spellcheck="false"><code>DEBUG</code></span><span class="">级别之下的也就是</span><span spellcheck="false"><code>NOTSET</code></span>级别的不会被输出。</p>
<p class="md-end-block" contenteditable="true">如果我们把级别设置为<span spellcheck="false"><code>INFO</code></span>，那么我们实例的输出应该是</p>
<pre class="lang:default decode:true md-fences md-end-block ty-contain-cm modeLoaded">2019/01/13 13:21:17 - Your Logger - INFO - this is info msg
2019/01/13 13:21:17 - Your Logger - WARNING - this is warn msg
2019/01/13 13:21:17 - Your Logger - ERROR - this is error msg</pre>
<p class="md-end-block" contenteditable="true">只会输出比INFO级别高的日志。</p>
<h2 class="md-end-block md-heading" contenteditable="true">Handler</h2>
<p class="md-end-block" contenteditable="true"><span class="">logging提供的Handler有很多，我简单列举几种</span></p>
<figure class="md-table-fig" contenteditable="false">
<table class="md-table">
<thead>
<tr class="md-end-block">
<th><span class="td-span" contenteditable="true">种类</span></th>
<th><span class="td-span" contenteditable="true">位置</span></th>
<th><span class="td-span" contenteditable="true"><span class="">用途</span></span></th>
</tr>
</thead>
<tbody>
<tr class="md-end-block">
<td><span class="td-span" contenteditable="true">StreamHandler</span></td>
<td><span class="td-span" contenteditable="true">logging.StreamHandler</span></td>
<td><span class="td-span" contenteditable="true">日志输出到流，可以是 sys.stderr，sys.stdout 或者文件</span></td>
</tr>
<tr class="md-end-block">
<td><span class="td-span" contenteditable="true">FileHandler</span></td>
<td><span class="td-span" contenteditable="true">logging.FileHandler</span></td>
<td><span class="td-span" contenteditable="true">日志输出到文件</span></td>
</tr>
<tr class="md-end-block">
<td><span class="td-span" contenteditable="true">SMTPHandler</span></td>
<td><span class="td-span" contenteditable="true">logging.handlers.SMTPHandler</span></td>
<td><span class="td-span" contenteditable="true">远程输出日志到邮件地址</span></td>
</tr>
<tr class="md-end-block">
<td><span class="td-span" contenteditable="true">SysLogHandler</span></td>
<td><span class="td-span" contenteditable="true">logging.handlers.SysLogHandler</span></td>
<td><span class="td-span" contenteditable="true">日志输出到syslog</span></td>
</tr>
<tr class="md-end-block">
<td><span class="td-span" contenteditable="true">HTTPHandler</span></td>
<td><span class="td-span" contenteditable="true">logging.handlers.HTTPHandler</span></td>
<td><span class="td-span" contenteditable="true">通过”GET”或者”POST”远程输出到HTTP服务器</span></td>
</tr>
</tbody>
</table>
</figure>
<h2 class="md-end-block md-heading" contenteditable="true">Formatter</h2>
<p class="md-end-block" contenteditable="true">fmt参数和datefmt两个参数分别对应日志记录的格式化和时间的格式化。</p>
<p class="md-end-block" contenteditable="true">fmt可用的占位符简单列举几种，更多请参考<span class=" md-link"><a spellcheck="false" href="https://docs.python.org/3/library/logging.html?highlight=logging%20threadname#logrecord-attributes">这里</a></span></p>
<figure class="md-table-fig" contenteditable="false">
<table class="md-table">
<thead>
<tr class="md-end-block">
<th><span class="td-span" contenteditable="true"><span class="">占位符</span></span></th>
<th><span class="td-span" contenteditable="true">作用</span></th>
</tr>
</thead>
<tbody>
<tr class="md-end-block">
<td><span class="td-span" contenteditable="true">%(levelname)s</span></td>
<td><span class="td-span" contenteditable="true">打印日志级别的名称</span></td>
</tr>
<tr class="md-end-block">
<td><span class="td-span" contenteditable="true">%(pathname)s</span></td>
<td><span class="td-span" contenteditable="true">打印当前执行程序的路径，其实就是sys.argv[0]。</span></td>
</tr>
<tr class="md-end-block">
<td><span class="td-span" contenteditable="true">%(filename)s</span></td>
<td><span class="td-span" contenteditable="true"><span class="">打印当前执行程序名。</span></span></td>
</tr>
<tr class="md-end-block">
<td><span class="td-span" contenteditable="true">%(funcName)s</span></td>
<td><span class="td-span" contenteditable="true">打印日志的当前函数。</span></td>
</tr>
<tr class="md-end-block">
<td><span class="td-span" contenteditable="true">%(lineno)d</span></td>
<td><span class="td-span" contenteditable="true">打印日志的当前行号。</span></td>
</tr>
<tr class="md-end-block">
<td><span class="td-span" contenteditable="true">%(asctime)s</span></td>
<td><span class="td-span" contenteditable="true">打印日志的时间。</span></td>
</tr>
<tr class="md-end-block">
<td><span class="td-span" contenteditable="true">%(thread)d</span></td>
<td><span class="td-span" contenteditable="true">打印线程ID。</span></td>
</tr>
<tr class="md-end-block">
<td><span class="td-span" contenteditable="true">%(threadName)s</span></td>
<td><span class="td-span" contenteditable="true">打印线程名称。</span></td>
</tr>
<tr class="md-end-block">
<td><span class="td-span" contenteditable="true">%(process)d</span></td>
<td><span class="td-span" contenteditable="true">打印进程ID。</span></td>
</tr>
<tr class="md-end-block">
<td><span class="td-span" contenteditable="true">%(processName)s</span></td>
<td><span class="td-span" contenteditable="true">打印线程名称。</span></td>
</tr>
<tr class="md-end-block">
<td><span class="td-span" contenteditable="true">%(module)s</span></td>
<td><span class="td-span" contenteditable="true">打印模块名称。</span></td>
</tr>
<tr class="md-end-block">
<td><span class="td-span" contenteditable="true">%(message)s</span></td>
<td><span class="td-span" contenteditable="true">打印日志信息。</span></td>
</tr>
</tbody>
</table>
</figure>
<h1 class="md-end-block md-heading" contenteditable="true">捕获Traceback</h1>
<pre class="lang:default decode:true md-fences md-end-block ty-contain-cm modeLoaded">try:
    result = 10 / 0
except Exception:
    logger.error('Faild to get result', exc_info=True)
    # 或者用下面这个
    # logging.exception('Error')
logger.info('Finished')</pre>
<p class="md-end-block" contenteditable="true">输出</p>
<pre class="lang:default decode:true md-fences md-end-block ty-contain-cm modeLoaded">2019/01/13 14:11:18 - Your Logger - ERROR - Faild to get result
Traceback (most recent call last):
  File "E:/Python/test.py", line 22, in &lt;module&gt;
    result = 10 / 0
ZeroDivisionError: division by zero
2019/01/13 14:11:18 - Your Logger - INFO - Finished</pre>
<p class="md-end-block" contenteditable="true"><span class="">这样会更合理的捕获异常信息。</span></p>
<h1 class="md-end-block md-heading" contenteditable="true">自定义日志级别</h1>
<pre class="lang:default decode:true md-fences md-end-block ty-contain-cm modeLoaded">import logging
​
INFO, WARN, ERROR, SUCCESS = range(1, 5)
# print(SYSINFO, WARN, ERROR, SUCCESS)
logging.addLevelName(INFO, '*')
logging.addLevelName(WARN, '!')
logging.addLevelName(ERROR, 'x')
logging.addLevelName(SUCCESS, '+')
​
logger = logging.getLogger('LOGGER')
handler = logging.StreamHandler()
formatter = logging.Formatter(fmt='%(asctime)s [%(levelname)s] %(message)s', datefmt='%Y/%m/%d %H:%M:%S')
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.setLevel(INFO)
​
logger.log(INFO, "INFO")
logger.log(WARN, "WARN")
logger.log(ERROR, "ERROR")
logger.log(SUCCESS, "SUCCESS")</pre>
<p class="md-end-block" contenteditable="true">输出</p>
<pre class="lang:default decode:true">2019/01/13 14:17:59 [*] INFO
2019/01/13 14:17:59 [!] WARN
2019/01/13 14:17:59 [x] ERROR
2019/01/13 14:17:59 [+] SUCCESS</pre>
<p>&nbsp;</p>
<p class="md-end-block" contenteditable="true">先定义级别和数值，然后调用<span class="" spellcheck="false"><code>addLevelName(级别名,'输出名')</code></span><span class="">。记得</span><span class=""><strong>数值不能小于等于0</strong></span>，注意输出日志的级别。</p>
<h1 class="md-end-block md-heading" contenteditable="true">给输出加上颜色</h1>
<p class="md-end-block" contenteditable="true">用到了一个第三方的脚本<span class="" spellcheck="false"><code>ansistrm.py</code></span><span class="">，下载地址</span><span class="md-link" spellcheck="false"><a href="https://gist.github.com/Y4er/6300ccff3a6628ea7bda24e514013476">https://gist.github.com/Y4er/6300ccff3a6628ea7bda24e514013476</a></span><span class=""> 原作者脚本不支持win10，我修复了一下。</span></p>
<p class="md-end-block" contenteditable="true">将这个脚本<span spellcheck="false"><code>ansistrm.py</code></span>和你的<span spellcheck="false"><code>log.py</code></span>放到同一目录，然后<span spellcheck="false"><code>log.py</code></span>如下内容</p>
<pre class="lang:default decode:true md-fences md-end-block ty-contain-cm modeLoaded">#!/usr/bin/env python3 
# -*- coding: utf-8 -*- 
# @Time : 2019/1/12 21:01 
# @Author : Y4er 
# @Site : http://Y4er.com/
# @File : log.py 
​
​
import logging
​
INFO, WARN, ERROR, SUCCESS = range(1, 5)
# print(SYSINFO, WARN, ERROR, SUCCESS)
logging.addLevelName(INFO, '*')
logging.addLevelName(WARN, '!')
logging.addLevelName(ERROR, 'x')
logging.addLevelName(SUCCESS, '+')
​
logger = logging.getLogger('YOUR LOGGER')
try:
    from ansistrm import ColorizingStreamHandler
​
    handle = ColorizingStreamHandler()
    handle.level_map[logging.getLevelName('*')] = (None, 'cyan', False)
    handle.level_map[logging.getLevelName('+')] = (None, 'green', False)
    handle.level_map[logging.getLevelName('x')] = (None, 'red', False)
    handle.level_map[logging.getLevelName('!')] = (None, 'yellow', False)
except Exception as e:
    print(e)
    handle = logging.StreamHandler()
​
formatter = logging.Formatter('%(asctime)s - [%(levelname)s]  %(message)s', '%Y/%m/%d %H:%M:%S')
handle.setFormatter(formatter)
logger.addHandler(handle)
logger.setLevel(INFO)
​
​
class LOGGER:
    @staticmethod
    def info(msg):
        return logger.log(INFO, msg)
​
    @staticmethod
    def warning(msg):
        return logger.log(WARN, msg)
​
    @staticmethod
    def error(msg):
        return logger.log(ERROR, msg)
​
    @staticmethod
    def success(msg):
        return logger.log(SUCCESS, msg)
​
​
LOGGER.info("INFO msg")
LOGGER.warning("warning msg")
LOGGER.error("error msg")
LOGGER.success("success msg")</pre>
<p class="md-end-block md-focus" contenteditable="true"><span class="md-expand">在这个脚本中，我写了一个类以及其下的四个静态方法，那么可以这么调用</span></p>
<pre class="lang:default decode:true  ">LOGGER.info("INFO msg")
LOGGER.warning("warning msg")
LOGGER.error("error msg")
LOGGER.success("success msg")</pre>
<p>&nbsp;</p>
<p class="md-end-block" contenteditable="true"><span class="">运行效果：</span></p>
<p class="md-end-block" contenteditable="true"><span class="md-image md-img-loaded" contenteditable="false" data-src="https://ws1.sinaimg.cn/large/006xriynly1fz4y1l55w9j30bo038dfx.jpg"><img src="https://ws1.sinaimg.cn/large/006xriynly1fz4y1l55w9j30bo038dfx.jpg" /></span></p>
<h1 class="md-end-block md-heading" contenteditable="true">写在文后</h1>
<p class="md-end-block" contenteditable="true">是时候抛弃<span spellcheck="false"><code>print</code></span><span class="">了！</span></p>
<p class="md-end-block" contenteditable="true"><span class="">参考链接</span></p>
<p class="md-end-block" contenteditable="true"><span class="md-link"><a spellcheck="false" href="https://cuiqingcai.com/6080.html">Python中logging模块的基本用法 &#8211; 崔庆才老师</a></span></p>
<p class="md-end-block" contenteditable="true"><span class="md-link"><a spellcheck="false" href="https://gist.github.com/vsajip/758430">原版ansistrm.py &#8211; vsajip</a></span></p>
<p class="md-end-block" contenteditable="true"><span class="md-link md-expand"><a spellcheck="false" href="https://gist.github.com/vsajip/758430#gistcomment-2764744">修复ansistrm.py以支持win10</a></span></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>【重写】百度站长Python主动推送</title>
		<link>/code/536.html</link>
		
		<dc:creator><![CDATA[Y4er]]></dc:creator>
		<pubDate>Sun, 26 Aug 2018 08:36:25 +0000</pubDate>
				<category><![CDATA[编程学习]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[工具]]></category>
		<category><![CDATA[脚本]]></category>
		<guid isPermaLink="false">/?p=536</guid>

					<description><![CDATA[第一版抓取的链接不是很到位，第二版使用BeautifulSoup来解析sitemap.xml提交，抓取更全。 学习是一件很开心的事情。 &#160; chabug一直不被百度收录，...]]></description>
										<content:encoded><![CDATA[<p>第一版抓取的链接不是很到位，第二版使用BeautifulSoup来解析sitemap.xml提交，抓取更全。</p>
<p>学习是一件很开心的事情。</p>
<p><a href="/wp-content/uploads/2018/08/2018081513421353.jpg"><img loading="lazy" class="aligncenter size-full wp-image-537" src="/wp-content/uploads/2018/08/2018081513421353.jpg" alt="" width="430" height="430" /></a></p>
<p>&nbsp;</p>
<p>chabug一直不被百度收录，谷歌收录飙到599的时候，百度仍然在30左右徘徊。无可奈何，写了一个主动提交的<span class="wpcom_tag_link"><a href="/tags/%e8%84%9a%e6%9c%ac" title="脚本" target="_blank">脚本</a></span>，来简化这一操作。</p>
<h1><a id="user-content-适用范围" class="anchor" href="https://github.com/Y4er/BaiduSubmit#%E9%80%82%E7%94%A8%E8%8C%83%E5%9B%B4" aria-hidden="true"></a>适用范围</h1>
<p>sitemap.xml类似于<a href="https://chabug.org/sitemap.xml" rel="nofollow">https://chabug.org/sitemap.xml</a> 我这种的，sitemap分类化可以直接食用。</p>
<p>WordPress装上插件<a href="https://wordpress.org/plugins/xml-sitemap-feed/" rel="nofollow">XML Sitemap &amp; Google News</a>可直接食用。</p>
<h1><a id="user-content-注意" class="anchor" href="https://github.com/Y4er/BaiduSubmit#%E6%B3%A8%E6%84%8F" aria-hidden="true"></a>注意</h1>
<p>先修改脚本里的API哦！</p>
<pre class="lang:default decode:true">#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# author:Y4er
import json
import requests
from bs4 import BeautifulSoup

headers = {
	'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36',
	'Content-Type': 'text/plain'
}

def sitemap(url):
	print('[*] 正在爬取sitemap')
	url = url + '/sitemap.xml'
	r = requests.get(url,headers=headers).text
	soup = BeautifulSoup(r,'html.parser')
	locs = soup.findAll('loc')
	urls = []
	for loc in locs:
		print(loc.text)
		req = requests.get(loc.text,headers=headers).text
		url = BeautifulSoup(req,'html.parser').findAll('loc')
		for i in url:
			urls.append(i.text)
		imgs = BeautifulSoup(req,'html.parser').findAll('image:loc')
		for i in imgs:
			urls.append(i.text)
	# for url in urls:
	# 	url = url.replace('\n')
	print('[*] 发现%s个链接' % len(list(set(urls))))
	return list(set(urls))

def submit(urls):
	try:	
		print('[*] 正在提交')
		api = '填写你自己的API'
		data = '\n'
		data = data.join(urls)
		req = requests.post(api,headers=headers,data=data)
		print('[+] 提交成功%s条' % json.loads(req.text)['success'])
		print('[+] 今天剩余%s条' % json.loads(req.text)['remain'])
	except:
		print('[-] 提交失败')

if __name__ == '__main__':
	urls = sitemap('/')
	submit(urls)</pre>
<p>&nbsp;</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Python脚本之CNVD按编号查详情</title>
		<link>/code/529.html</link>
		
		<dc:creator><![CDATA[Y4er]]></dc:creator>
		<pubDate>Fri, 10 Aug 2018 08:13:15 +0000</pubDate>
				<category><![CDATA[编程学习]]></category>
		<category><![CDATA[python]]></category>
		<guid isPermaLink="false">/?p=529</guid>

					<description><![CDATA[闲得无聊，我只能继续重复造轮子度日了。 参数说明： python cnvd.py -n 编号1,编号2 运行截图 上脚本。 #!/usr/bin/env python3 # -*-...]]></description>
										<content:encoded><![CDATA[<p>闲得无聊，我只能继续重复造轮子度日了。</p>
<h1>参数说明：</h1>
<pre class="">python cnvd.py -n 编号1,编号2</pre>
<h1>运行截图</h1>
<p><a href="/wp-content/uploads/2018/08/2018081016081320.jpg"><img loading="lazy" class="aligncenter size-full wp-image-530" src="/wp-content/uploads/2018/08/2018081016081320.jpg" alt="" width="1223" height="639" /></a></p>
<p><a href="/wp-content/uploads/2018/08/2018081016085643.jpg"><img loading="lazy" class="aligncenter size-full wp-image-531" src="/wp-content/uploads/2018/08/2018081016085643.jpg" alt="" width="1191" height="790" /></a></p>
<p>上脚本。</p>
<pre class="lang:default decode:true">#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# author:Y4er

import requests
import argparse
import progressbar
import prettytable as pt
from bs4 import BeautifulSoup

headers = {
	'Referer': 'http://www.cnvd.org.cn/flaw/list.htm',
	'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'
}

# 一个编号处理方法
def one(number):
	url = 'http://www.cnvd.org.cn/flaw/show/' + number
	tb = getinfo(url,number)
	print(tb)
	
# 多个编号
def many(nums):
	tbs = []
	p = progressbar.ProgressBar()
	for number in p(nums):
		url = 'http://www.cnvd.org.cn/flaw/show/' + number
		tb = getinfo(url,number)
		tbs.append(tb)
	for tb in tbs:
		print(tb)

# 获取表格
def getinfo(url,number):
	tb = pt.PrettyTable(["title","value"])
	# 获取源码
	r = requests.get(url,headers=headers).text
	soup = BeautifulSoup(r,'html.parser')
	# 获取数据	
	trs = soup.findAll(name="tr")[:13]
	for idx,tr in enumerate(trs):
		# print(idx,tr.get_text())
		tds = tr.findAll(name="td")
		title = tds[0].get_text().strip()
		value = tds[1].get_text().strip().replace('\r','').replace('\t','').replace('\n','')
		if len(value)&gt;=60:
			value = value[:60] + '...'
		tb.add_row([title,value])
	return tb


if __name__ == '__main__':
	# 命令行参数
	parser = argparse.ArgumentParser()
	parser.add_argument('-n',dest='number',help='input your cnvd number',required=True) 
	args = parser.parse_args()
	if args.number==None:
		print(args.print_help)
	# 切片 判断是一个编号还是多个
	nums = args.number.split(',')
	if len(nums) == 1:
		one(nums[0])
	else:
		many(nums)</pre>
<p><a href="https://github.com/ChaBug/Python_study/tree/master/CNVD">GitHub</a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Python3多线程端口扫描脚本以及渗透常用端口号</title>
		<link>/tools/510.html</link>
		
		<dc:creator><![CDATA[Y4er]]></dc:creator>
		<pubDate>Sun, 05 Aug 2018 06:53:08 +0000</pubDate>
				<category><![CDATA[工具分享]]></category>
		<category><![CDATA[编程学习]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[多线程]]></category>
		<category><![CDATA[工具]]></category>
		<category><![CDATA[扫描]]></category>
		<category><![CDATA[端口]]></category>
		<guid isPermaLink="false">/?p=510</guid>

					<description><![CDATA[&#160; 闲着无聊，总不能把python丢下，就写了这个小脚本，最近也慢慢在写自己用的工具，毕竟自己写的才是最顺手的。 参数说明 -a 扫描的IP地址 -t 超时 -p 扫描端...]]></description>
										<content:encoded><![CDATA[<p>&nbsp;</p>
<p>闲着无聊，总不能把<span class="wpcom_tag_link"><a href="/tags/python" title="python" target="_blank">python</a></span>丢下，就写了这个小脚本，最近也慢慢在写自己用的<span class="wpcom_tag_link"><a href="/tags/%e5%b7%a5%e5%85%b7" title="工具" target="_blank">工具</a></span>，毕竟自己写的才是最顺手的。</p>
<p><a href="/wp-content/uploads/2018/08/2018080514553069.png"><img loading="lazy" class="aligncenter size-full wp-image-511" src="/wp-content/uploads/2018/08/2018080514553069.png" alt="" width="472" height="147" /></a></p>
<h1>参数说明</h1>
<p>-a <span class="wpcom_tag_link"><a href="/tags/%e6%89%ab%e6%8f%8f" title="扫描" target="_blank">扫描</a></span>的IP地址</p>
<p>-t 超时</p>
<p>-p 扫描<span class="wpcom_tag_link"><a href="/tags/%e7%ab%af%e5%8f%a3" title="端口" target="_blank">端口</a></span> 支持1-65535格式，以-号连接</p>
<pre class="lang:default decode:true"> ____            _   ____
|  _ \ ___  _ __| |_/ ___|  ___ __ _ _ __
| |_) / _ \| '__| __\___ \ / __/ _` | '_ \
|  __/ (_) | |  | |_ ___) | (_| (_| | | | |
|_|   \___/|_|   \__|____/ \___\__,_|_| |_|

Have fun. Author:Y4er
usage: portscan.py [-h] -a HOST -t TIMEOUT [-p PORT]

optional arguments:
  -h, --help  show this help message and exit
  -a HOST     target host
  -t TIMEOUT  timeout
  -p PORT     target port</pre>
<h1>脚本代码</h1>
<pre class="lang:default decode:true">#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# author:Y4er

import socket
import argparse
import threading

def banner():
	print(r'''
 ____            _   ____                  
|  _ \ ___  _ __| |_/ ___|  ___ __ _ _ __  
| |_) / _ \| '__| __\___ \ / __/ _` | '_ \ 
|  __/ (_) | |  | |_ ___) | (_| (_| | | | |
|_|   \___/|_|   \__|____/ \___\__,_|_| |_|
                                           
Have fun. Author:Y4er''')

def portscan(ip,port,timeout):
	try:
		socket.setdefaulttimeout(timeout)
		s = socket.socket()
		s.connect((ip,port))
		print('[+] {} is open.'.format(port))
		s.close()
	except:
		print('[-] {} is close.'.format(port))
	finally:
		pass

class MyThread(threading.Thread):
	"""docstring for MyThread"""
	def __init__(self,host,port,timeout):
		super(MyThread, self).__init__()
		self.host = host
		self.port = port
		self.timeout = timeout

	def run(self):
		portscan(self.host,self.port,self.timeout)


if __name__ == '__main__':
	def_ports = [21,22,23,25,80,110,137,138,139,443,445,873,888,1025,1433,1521,2082,2083,2222,3306,3311,3312,3389,4899,5432,5900,6379,7001,7002,7778,8000,8080,8888,11211,27017,43958,50000,65500]

	parser = argparse.ArgumentParser(usage=banner())
	parser.add_argument('-a',help='target host',dest='host',required=True)
	parser.add_argument('-t',help='timeout',dest='timeout',type=int,required=True)
	parser.add_argument('-p',help='target port',dest='port',required=False)
	args = parser.parse_args()
	threads = []

	if args.port:
		if '-' in args.port:
			limits = args.port.split('-')
			limits = list(map(int,limits))
			for port in range(limits[0],limits[1]+1):
				t = MyThread(args.host,port,args.timeout)
				threads.append(t)
	else:	
		for port in def_ports:
			t = MyThread(args.host,port,args.timeout)
			threads.append(t)
	for t in threads:
		t.start()
	for t in threads:
		t.join()</pre>
<p>&nbsp;</p>
<p><span class="wpcom_tag_link"><a href="/tags/%e5%a4%9a%e7%ba%bf%e7%a8%8b" title="多线程" target="_blank">多线程</a></span>的线程锁没加，也不会加，可能数据会有点乱，但是没事，看不瞎 &#8211; -。</p>
<h1>附上web中常用端口号</h1>
<pre class="lang:default decode:true">21 ftp 
 
22 SSH 
 
23 Telnet 
 
80 web 
 
80-89 web 
 
161 SNMP 
 
389 LDAP 
 
443 SSL心脏滴血以及一些web漏洞测试 
 
445 SMB 
 
512,513,514 Rexec 
 
873 Rsync未授权 
 
1025,111 NFS 
 
1433 MSSQL 
 
1521 Oracle:(iSqlPlus Port:5560,7778) 
 
2082/2083 cpanel主机管理系统登陆 （国外用较多）
  
2222 DA虚拟主机管理系统登陆 （国外用较多） 
 
2601,2604 zebra路由，默认密码zebra
  
3128 squid代理默认端口，如果没设置口令很可能就直接漫游内网了 
 
3306 MySQL 
 
3312/3311 kangle主机管理系统登陆 
 
3389 远程桌面 
 
4440 rundeck 参考WooYun: 借用新浪某服务成功漫游新浪内网 
 
5432 PostgreSQL 
 
5900 vnc 
 
5984 CouchDB http://xxx:5984/_utils/ 
 
6082 varnish 参考WooYun: Varnish HTTP accelerator CLI 未授权访问易导致网站被直接篡改或者作为代理进入内网 
 
6379 redis未授权 
 
7001,7002 WebLogic默认弱口令，反序列 
 
7778 Kloxo主机控制面板登录 
 
8000-9090 都是一些常见的web端口，有些运维喜欢把管理后台开在这些非80的端口上 
 
8080 tomcat/WDCP主机管理系统，默认弱口令 
 
8080,8089,9090 JBOSS 
 
8083 Vestacp主机管理系统 （国外用较多） 
 
8649 ganglia 
 
8888 amh/LuManager 主机管理系统默认端口 
 
9200,9300 elasticsearch 参考WooYun: 多玩某服务器ElasticSearch命令执行漏洞 
 
10000 Virtualmin/Webmin 服务器虚拟主机管理系统 
 
11211 memcache未授权访问 
 
27017,27018 Mongodb未授权访问 
 
28017 mongodb统计页面 
 
50000 SAP命令执行 
 
50070,50030 hadoop默认端口未授权访问</pre>
<p>这些差不多都写到了py脚本里。自用。</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Django中自定义Form样式</title>
		<link>/code/432.html</link>
		
		<dc:creator><![CDATA[Y4er]]></dc:creator>
		<pubDate>Fri, 22 Jun 2018 15:16:00 +0000</pubDate>
				<category><![CDATA[编程学习]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[python]]></category>
		<guid isPermaLink="false">/?p=384</guid>

					<description><![CDATA[最近在学习Django的过程中，发现Django里面对表单的支持非常棒，简化了很多操作，例如可以很方便的生成Html表单，对表单进行验证以及最终的数据存储等等，简单的一个实例如下：...]]></description>
										<content:encoded><![CDATA[<p><a href="/wp-content/uploads/2018/06/2.jpg"><img loading="lazy" class="alignnone size-full wp-image-385" src="/wp-content/uploads/2018/06/2.jpg" alt="" width="500" height="228" /></a><br />
最近在学习Django的过程中，发现Django里面对表单的支持非常棒，简化了很多操作，例如可以很方便的生成Html表单，对表单进行验证以及最终的数据存储等等，简单的一个实例如下：</p>
<pre class="lang:default decode:true " >class AccountForm(forms.ModelForm):
nick_name = forms.CharField(label=u'用户昵称', \
help_text="请输入用户昵称")
email = forms.EmailField(label=u'电子邮件', \
help_text=u'请输入常用邮箱')
password = forms.CharField(label=u'密码', \
help_text=u'请输入密码', \
widget=forms.PasswordInput())
re_password = forms.CharField(label=u'确认密码', \
help_text=u'请再次确认密码', \
widget=forms.PasswordInput())

​
def clean_re_password(self):
password = self.cleaned_data.get("password")
re_password = self.cleaned_data.get("re_password")
if password and re_password and password != re_password:
raise forms.ValidationError((u'密码输入不一致'))
if len(password) &amp;lt; 6:
raise forms.ValidationError((u'密码至少6位'))
return re_password
​
class Meta:
model = Account
fields = ('nick_name', 'email', 'password')</pre>
<p>在模板中只需要简单的添加</p>
<pre class="lang:default decode:true " >&lt;div class="weui_cells_form"&gt;
    &lt;form id="user_form" method="post" action="url_to_submit_form"
        &lt;!-- csrf_token fields is necessary for securty --&gt;
        {% csrf_token %}
        {{account_form}}
        &lt;input type="submit" name="submit" value="注册" /&gt;
    &lt;/form&gt;
&lt;/div&gt;</pre>
<p>这样就完成了简单的表单设计。</p>
<p>Django的这种方法确实很简单，但是Django固有的表单样式比较单一，虽然可以通过widget属性添加css样式，但是明显DIY程度不够高，本着前后端分离的原则，需要将表单的样式彻底分离出来，做到完全定制。</p>
<p>具体的表单自定义方式实际在Django的官方文档里面也有提及</p>
<pre class="lang:default decode:true " >Useful attributes on {{ field }} include:
{{ field.label }}
The label of the field, e.g. Email address.
{{ field.label_tag }}
The field’s label wrapped in the appropriate HTML &lt;label&gt; tag. This includes the form’s label_suffix. For example, the default label_suffix is a colon:
&lt;label for="id_email"&gt;Email address:&lt;/label&gt;
{{ field.id_for_label }}
The ID that will be used for this field (id_email in the example above). If you are constructing the label manually, you may want to use this in lieu of label_tag. It’s also useful, for example, if you have some inline JavaScript and want to avoid hardcoding the field’s ID.
{{ field.value }}
The value of the field. e.g someone@example.com.
{{ field.html_name }}
The name of the field that will be used in the input element’s name field. This takes the form prefix into account, if it has been set.
{{ field.help_text }}
Any help text that has been associated with the field.
{{ field.errors }}
Outputs a &lt;ul class="errorlist"&gt; containing any validation errors corresponding to this field. You can customize the presentation of the errors with a {% for error in field.errors %} loop. In this case, each object in the loop is a simple string containing the error message.
{{ field.is_hidden }}</pre>
<p>通过这种方式，就可以实现对Form的完全定制，比如采用微信的样式：</p>
<pre class="lang:default decode:true " >&lt;div class="weui_cells weui_cells_form"&gt;
    {% for item in login_form %}
        &lt;div class="weui_cell"&gt;
            &lt;div class="weui_cell_hd"&gt;
                &lt;label class="weui_label"&gt;{{item.label}}&lt;/label&gt;
            &lt;/div&gt;
            &lt;div class="weui_cell_bd weui_cell_primary"&gt;
                &lt;input class="weui_input" placeholder="{{item.help_text}}" id="{{item.id_for_label}}" name="{{item.html_name}}" type="{{item.field.widget.input_type}}" /&gt;
            &lt;/div&gt;
            {% for error in item.errors %}
                    &lt;p&gt;{{error}}&lt;/p&gt;
                {% endfor%}
        &lt;/div&gt;
&lt;/div&gt;</pre>
<p>在上面的&#8221;item.field.widget.input_type&#8221;这个域在文档中也并未提及，但是这个域又相当重要，因为像输入密码日期之类的类型都是靠这个域来定义的，最后这个域是通过读Django的源代码得到的，也算是一种获得Doc的途径吧。</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>python 文件操作</title>
		<link>/code/430.html</link>
		
		<dc:creator><![CDATA[Y4er]]></dc:creator>
		<pubDate>Thu, 21 Jun 2018 10:38:35 +0000</pubDate>
				<category><![CDATA[编程学习]]></category>
		<category><![CDATA[python]]></category>
		<guid isPermaLink="false">/?p=369</guid>

					<description><![CDATA[模式 描述 r 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 rb 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。一般用于非文本文...]]></description>
										<content:encoded><![CDATA[<table class="reference">
<tbody>
<tr>
<th>模式</th>
<th>描述</th>
</tr>
<tr>
<td>r</td>
<td>以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。</td>
</tr>
<tr>
<td>rb</td>
<td>以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。一般用于非文本文件如图片等。</td>
</tr>
<tr>
<td>r+</td>
<td>打开一个文件用于读写。文件指针将会放在文件的开头。</td>
</tr>
<tr>
<td>rb+</td>
<td>以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。一般用于非文本文件如图片等。</td>
</tr>
<tr>
<td>w</td>
<td>打开一个文件只用于写入。如果该文件已存在则打开文件，并从开头开始编辑，即原有内容会被删除。如果该文件不存在，创建新文件。</td>
</tr>
<tr>
<td>wb</td>
<td>以二进制格式打开一个文件只用于写入。如果该文件已存在则打开文件，并从开头开始编辑，即原有内容会被删除。如果该文件不存在，创建新文件。一般用于非文本文件如图片等。</td>
</tr>
<tr>
<td>w+</td>
<td>打开一个文件用于读写。如果该文件已存在则打开文件，并从开头开始编辑，即原有内容会被删除。如果该文件不存在，创建新文件。</td>
</tr>
<tr>
<td>wb+</td>
<td>以二进制格式打开一个文件用于读写。如果该文件已存在则打开文件，并从开头开始编辑，即原有内容会被删除。如果该文件不存在，创建新文件。一般用于非文本文件如图片等。</td>
</tr>
<tr>
<td>a</td>
<td>打开一个文件用于追加。如果该文件已存在，文件指针将会放在文件的结尾。也就是说，新的内容将会被写入到已有内容之后。如果该文件不存在，创建新文件进行写入。</td>
</tr>
<tr>
<td>ab</td>
<td>以二进制格式打开一个文件用于追加。如果该文件已存在，文件指针将会放在文件的结尾。也就是说，新的内容将会被写入到已有内容之后。如果该文件不存在，创建新文件进行写入。</td>
</tr>
<tr>
<td>a+</td>
<td>打开一个文件用于读写。如果该文件已存在，文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在，创建新文件用于读写。</td>
</tr>
<tr>
<td>ab+</td>
<td>以二进制格式打开一个文件用于追加。如果该文件已存在，文件指针将会放在文件的结尾。如果该文件不存在，创建新文件用于读写。</td>
</tr>
</tbody>
</table>
<p>下图很好的总结了这几种模式：</p>
<p><img src="http://www.runoob.com/wp-content/uploads/2013/11/2112205-861c05b2bdbc9c28.png" /></p>
<table class="reference">
<thead>
<tr>
<th>模式</th>
<th>r</th>
<th>r+</th>
<th>w</th>
<th>w+</th>
<th>a</th>
<th>a+</th>
</tr>
</thead>
<tbody>
<tr>
<td>读</td>
<td>+</td>
<td>+</td>
<td></td>
<td>+</td>
<td></td>
<td>+</td>
</tr>
<tr>
<td>写</td>
<td></td>
<td>+</td>
<td>+</td>
<td>+</td>
<td>+</td>
<td>+</td>
</tr>
<tr>
<td>创建</td>
<td></td>
<td></td>
<td>+</td>
<td>+</td>
<td>+</td>
<td>+</td>
</tr>
<tr>
<td>覆盖</td>
<td></td>
<td></td>
<td>+</td>
<td>+</td>
<td></td>
<td></td>
</tr>
<tr>
<td>指针在开始</td>
<td>+</td>
<td>+</td>
<td>+</td>
<td>+</td>
<td></td>
<td></td>
</tr>
<tr>
<td>指针在结尾</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>+</td>
<td>+</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>bing每日一图抓取</title>
		<link>/code/403.html</link>
		
		<dc:creator><![CDATA[Y4er]]></dc:creator>
		<pubDate>Sat, 21 Apr 2018 17:31:59 +0000</pubDate>
				<category><![CDATA[编程学习]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[图片]]></category>
		<guid isPermaLink="false">/?p=338</guid>

					<description><![CDATA[#!/usr/bin/env python3 # coding=utf-8 import requests import re idx=input(&#34;抓取今天的输入0，昨...]]></description>
										<content:encoded><![CDATA[<pre><code>#!/usr/bin/env python3
# coding=utf-8
import requests
import re
idx=input(&quot;抓取今天的输入0，昨天的输入1，以此类推：&quot;)
n=input(&quot;你要获取多少张图(最多8张)：&quot;);
print(n+&quot;张图正在抓取！&quot;)
base_url='https://cn.bing.com/'
url='https://cn.bing.com/HPImageArchive.aspx?idx='+str(idx)+'&amp;n='+str(n)
r=requests.get(url).text
pics=re.findall('[^\s]*',r)
for pic in pics:
    print(base_url+pic[5:-6])</code></pre>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>傲天带你学Python系列直播</title>
		<link>/others/368.html</link>
		
		<dc:creator><![CDATA[Y4er]]></dc:creator>
		<pubDate>Sat, 03 Mar 2018 20:18:10 +0000</pubDate>
				<category><![CDATA[其他杂乱]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[教程]]></category>
		<guid isPermaLink="false">/?p=266</guid>

					<description><![CDATA[澳门首家线上Python上线了，性感傲天在线直播，带你走进Python的奇妙世界！ 不开玩笑，回归正题，朋友@傲天自己搞得公开课，我帮他宣传下。 傲天师傅没少帮我解决Python学...]]></description>
										<content:encoded><![CDATA[<blockquote><p>澳门首家线上Python上线了，性感傲天在线直播，带你走进Python的奇妙世界！</p></blockquote>
<p>不开玩笑，回归正题，朋友<a href="https://www.allsrc.cn/">@傲天</a>自己搞得公开课，我帮他宣传下。</p>
<p>傲天师傅没少帮我解决Python学习中的问题，他说他会十几种语言@(不高兴)，我不信@(捂嘴笑)，然后他就给我举例出来了：<code>php js node html css c <span class="wpcom_tag_link"><a href="/tags/python" title="python" target="_blank">python</a></span> c++ st ld</code>。好吧，说了这么多，我只想说这确实是个大佬，有兴趣的同学可以看一下。</p>
<p><strong>哦对了，他讲的是Python3哦！</strong></p>
<h1>目录</h1>
<ol>
<li>Python第一节&#8211;前言</li>
<li>Python第二节&#8211;运算符和布尔运算</li>
<li>Python第三节&#8211;Python版本和关键字</li>
<li>Python第四节&#8211;讲解函数</li>
<li>Python第五节&#8211;变量</li>
<li>Python第六节&#8211;条件控制和循环</li>
</ol>
<p>更多章节陆陆续续更新中&#8230;</p>
<h1>直播地址</h1>
<p>他喜欢用QQ群解决问题，群号是:<a href="https://jq.qq.com/?_wv=1027&#038;k=5Y1ShFa">518750457</a></p>
<p>当然，录像也有，传到了B站。地址在这：<a href="https://www.bilibili.com/video/av20287067/">https://www.bilibili.com/video/av20287067/</a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>[干货]Python爬虫-爬取各个地区的天气.</title>
		<link>/code/323.html</link>
		
		<dc:creator><![CDATA[Y4er]]></dc:creator>
		<pubDate>Tue, 16 Jan 2018 11:50:00 +0000</pubDate>
				<category><![CDATA[编程学习]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[爬虫]]></category>
		<guid isPermaLink="false">/?p=17</guid>

					<description><![CDATA[大家好，我是傲天 好，开始正题，开始我们的爬虫! 首先配上效果图 OK，先说一下我的运行环境 Windows7 Python3.6 接下来是依赖库 BeautifulSoup re...]]></description>
										<content:encoded><![CDATA[<blockquote><p>大家好，我是傲天</p></blockquote>
<hr />
<p>好，开始正题，开始我们的<span class="wpcom_tag_link"><a href="/tags/%e7%88%ac%e8%99%ab" title="爬虫" target="_blank">爬虫</a></span>!</p>
<h1>首先配上效果图</h1>
<p><img src="https://ws1.sinaimg.cn/large/006xriynly1fniq48fh4rj30go09dgm3.jpg" alt="效果" title="效果"></p>
<p>OK，先说一下我的运行环境</p>
<ul>
<li>Windows7</li>
<li>Python3.6</li>
</ul>
<p>接下来是依赖库</p>
<ul>
<li>BeautifulSoup</li>
<li>requests</li>
<li>pinyin</li>
</ul>
<h1>进入正题贴代码</h1>
<pre><code>import requests
import pinyin
from bs4 import BeautifulSoup
from os import system
class Get_url_weather(object):
    #实现请求一个天气的URL，并对数据进行解析
    def __init__(self, url, timeout=2):
        #    请扔进来一个url,还有一个超时查询默认为2秒吧
        self.r = requests.get(url, timeout=timeout)
        if self.r.status_code == 404:
            print(&quot;出现错误,请检查输入是否正确，如若多次输入不正确，说明该程序无法查询到你地址的天气&quot;)
    def get(self):
        soup = self.get_soup()
        #因为我们想要的信息都在一个dl里，class=&quot;weather_info&quot;
        html = self.get_dl_weather_ifno(soup)
        a = []
        a.append(&quot;标头:{}&quot;.format(html.img[&quot;alt&quot;]))
        a.append(&quot;地区:{}&quot;.format(html.dd.h2.text))
        a.append(&quot;{}&quot;.format(html.find(&quot;dd&quot;, class_=&quot;kongqi&quot;).h6.text))
        a.append(&quot;{}&quot;.format(html.find(&quot;dd&quot;, class_=&quot;kongqi&quot;).span.text)[:9])
        a.append(&quot;{}&quot;.format(html.find(&quot;dd&quot;, class_=&quot;kongqi&quot;).span.text)[9:])
        a.append(&quot;{}&quot;.format(html.find(&quot;dd&quot;, class_=&quot;shidu&quot;).b.text))
        a.append(&quot;{}&quot;.format(html.find(&quot;dd&quot;, class_=&quot;shidu&quot;).find_all(&quot;b&quot;)[1].text))
        a.append(&quot;{}&quot;.format(html.find(&quot;dd&quot;, class_=&quot;shidu&quot;).find_all(&quot;b&quot;)[2].text))
        a.append(&quot;{}&quot;.format(html.find(&quot;dd&quot;, class_=&quot;kongqi&quot;).h5.text))
        a.append(&quot;当前时间:{}&quot;.format(html.find(&quot;dd&quot;, class_=&quot;week&quot;).text))
        a.append(&quot;当前天气:{}&quot;.format(html.find(&quot;span&quot;).b.text))
        a.append(&quot;全天温度:{}&quot;.format(html.find(&quot;span&quot;).text))
        return a
    def get_soup(self):
        return(BeautifulSoup(self.r.text, &quot;html.parser&quot;))
    def get_dl_weather_ifno(self, soup):
        return (soup.find(&quot;dl&quot;, attrs={'class':'weather_info'}))
if __name__ == &quot;__main__&quot;:
    URL = &quot;http://www.tianqi.com/&quot;
    url_path = pinyin.get(input(&quot;请输入地区名(不需要带市或省):&quot;), format=&quot;strip&quot;)
    URL = URL+url_path
    Data = Get_url_weather(URL)
    data = Data.get()
    print('\n'.join(data))
    system(&quot;pause&quot;)
    #print(str(pinyin.get(&quot;你好&quot;, format=&quot;strip&quot;)))</code></pre>
<p>需要学习爬虫的 交流群:62851737</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
