主要针对以下四种反爬技术:Useragent过滤;模糊的Javascript重定向;验证码;请求头一致性检查。
高级网络爬虫技术:绕过 “403 Forbidden”,验证码等
爬虫的完整代码可以在 github 上对应的仓库里找到。
加vx:tanzhouyiwan或qq群813622576免费领取学习资料
简介
我从不把爬取网页当做是我的一个爱好或者其他什么东西,但是我确实用网络爬虫做过很多事情。因为我所处理的许多工作都要求我得到无法以其他方式获得的数据。我需要为 Intoli 做关于游戏数据的静态分析,所以我爬取了Google应用商店的数据来寻找最新被下载的APK。Pointy Ball插件需要聚合来自不同网站的梦幻足球(游戏)的预测数据,最简单的方式就是写一个爬虫。在我在考虑这个问题的之前,我大概已经写了大约 40~50 个爬虫了。我不太记得当时我对我家人撒谎说我已经抓取了多少 TB 的数据….,但是我确实很接近那个数字了。
我尝试使用 xray/cheerio、nokogiri 和一些其他的工具。但我总是会回到我个人的最爱 Scrapy。在我看来,Scrapy是一个出色的软件。我对这款软件毫无保留的赞美是有原因的,它的用法非常符合直觉,学习曲线也很平缓。
你可以阅读Scrapy的教程,在几分钟内就可以让你的第一个爬虫运行起来。然后,当你需要做一些更复杂的事情的时候,你就会发现,有一个内置的、有良好文档说明的方式来做到这一点。这个框架有大量的内置功能,但是它的结构使得在你用到这些功能之前,不会妨碍到你。当你最终确实需要某些默认不存在的功能的时候,比如说,因为访问了太多的 URL 链接以至于无法存储到内存中,需要一个用于去重的 bloom filter(布隆过滤器),那么通常来说这就和继承其中的组件,然后做一点小改动一样简单。一切都感觉如此简单,而且scrapy是我书中一个关于良好软件设计的例子。
我很久以前就想写一个高级爬虫教程了。这给我一个机会来展示scrapy的可扩展性,同时解决实践中出现的现实问题。尽管我很想做这件事,但是我还是无法摆脱这样一个事实:因为发布一些可能导致他人服务器由于大量的机器人流量受到损害的文章,就像是一个十足的坏蛋。
只要遵循几个基本的规则,我就可以在爬取那些有反爬虫策略的网站的时候安心地睡个好觉。换句话说,我让我的请求频率和手动浏览的访问频率相当,并且我不会对数据做任何令人反感的事情。这样就使得运行爬虫收集数据基本上和以其他主要的手动收集数据的方法无法区分。但即使我遵守了这些规则,我仍感觉为人们实际想要爬取的网站写一个教程有很大的难度。
直到我遇到一个叫做Zipru的BT下载网站,这件事情仍然只是我脑海里一个模糊的想法。这个网站有多个机制需要高级爬取技术来绕过,但是它的 robots.txt 文件却允许爬虫爬取。此外,其实我们不必去爬取它。因为它有开放的API,同样可以得到全部数据。如果你对于获得torrent的数据感兴趣,那就只需要使用这个API,这很方便。
在本文的剩余部分,我将带领你写一个爬虫,处理验证码和解决我们在Zipru网站遇到的各种不同的挑战。样例代码无法被正常运行因为 Zipru 不是一个真实存在的网站,但是爬虫所使用的技术会被广泛应用于现实世界中的爬取中。因此这个代码在另一个意义上来说又是完整的。我们将假设你已经对 Python 有了基本的了解,但是我仍会尽力让那些对于 Scrapy 一无所知的人看懂这篇文章。如果你觉得进度太快,那么花几分钟的时间阅读一下Scrapy官网教程吧。
建立工程项目
我们会在 virtualenv 中建立我们的项目,这可以让我们封装一下依赖关系。首先我们在~/scrapers/zipru
中创建一个virtualenv ,并且安装scrapy包。
你运行的终端将被配置为使用本地的virtualenv。如果你打开另一个终端,那么你就需要再次运行. ~/scrapers/zipru/env/bin/active
命令 (否则你有可能得到命令或者模块无法找到的错误消息)。
现在你可以通过运行下面的命令来创建一个新的项目框架:
这样就会创建下面的目录结构。
大多数默认情况下产生的这些文件实际上不会被用到,它们只是建议以一种合理的方式来构建我们的代码。从现在开始,你应该把 ~/scrapers/zipru/zipru_scraper
当做这个项目的根目录。这里是任何scrapy命令运行的目录,同时也是所有相对路径的根。
添加一个基本的爬虫功能
现在我们需要添加一个Spieder类来让我们的scrapy真正地做一些事情。Spider类是scrapy爬虫用来解析文本,爬取新的url链接或是提取数据的一个类。我们非常依赖于默认Spider类的实现,以最大限度地减少我们必须要编写的代码量。这里要做的事情看起来有点自动化,但假如你看过文档,事情会变得更加简单。
首先,在zipru_scraper/spiders/
目录下创建一个文件,命名为 zipru_spider.py
,输入下面内容。
你可以在上面的网页中看到许多指向其他页面的连接。我们想让我们的爬虫跟踪这些链接,并且解析他们的内容。为了完成这个任务,我们首先需要识别出这些链接并且弄清楚他们指向的位置。
在这个阶段,DOM检查器将起到很大的助力。如果你右击其中的一个页面链接,在DOM检查器里面查看它,然后你就会看到指向其他页面的链接看起来像是这样的:
接下来我们需要为这些链接构造一个选择器表达式。有几种类型似乎用css或者xpath选择器进行搜索更适合,所以我通常倾向于灵活地混合使用这几种选择器。我强烈推荐学习xpath ,但是不幸的是,它有点超出了本教程的范围。我个人认为xpath对于网络爬虫,web UI 测试,甚至一般的web开发来说都是不可或缺的。我接下来仍然会使用css选择器,因为它对于大多数人来说可能比较熟悉。
要选择这些页面链接,我们可以把 a[title ~= page]
作为一个 css 选择器,来查找标题中有 “page” 字符的
标签。如果你在 DOM 检查器中按 ctrl-f
,那么你就会发现你也可以使用这个css表达式作为一条查找语句(也可以使用xpath)。这样我们就可以循环查看所有的匹配项了。这是一个很棒的方法,可以用来检查一个表达式是否有效,并且表达式足够明确不会在不小心中匹配到其他的标签。我们的页面链接选择器同时满足了这两个条件。
为了讲解我们的爬虫是怎样发现其他页面的,我们在 ZipruSpider
类中添加一个 parse(response)
方法,就像下面这样:
当我们开始爬取的时候,我们添加到 start_urls
中的链接将会被自动获取到,响应内容会被传递到 parse(response)
方法中。之后我们的代码就会找到所有指向其他页面的链接,并且产生新的请求对象,这些请求对象将使用同一个 parse(response)
作为回调函数。这些请求将被转化成响应对象,只要 url 仍然产生,响应就会持续地返回到 parse(response)
函数(感谢去重器)。
我们的爬虫已经可以找到了页面中列出的所有不同的页面,并且对它们发出了请求,但我们仍然需要提取一些对爬虫来说有用的数据。torrent 列表位于 标签之内,并且有属性 class="list2at"
,每个单独的 torrent 都位于带有属性 class="lista2"
的 标签,其中的每一行都包含 8 个 标签,分别与 “类别”,“文件”,“添加时间”,“文件大小”,“保种的人”,“下载文件的人”,“文件描述”,和“上传者”相对应。在代码中查看其它的细节可能是最简单的方法,下面是我们修改后的 parse(response)
方法:
我们的 parse(response)
方法现在能够返回字典类型的数据,并且根据它们的类型自动区分请求。每个字典都会被解释为一项,并且作为爬虫数据输出的一部分。
如果我们只是爬取大多数常见的网站,那我们已经完成了。我们只需要使用下面的命令来运行:
几分钟之后我们本应该得到一个 [JSON Lines] 格式 torrents.jl
文件,里面有我们所有的torrent 数据。取而代之的是我们得到下面的错误信息(和一大堆其他的东西):
我好气啊!我们现在必须变得更聪明来获得我们完全可以从公共API得到的数据,因为上面的代码永远都无法爬取到那些数据。
简单的问题
我们的第一个请求返回了一个 403
响应,所以这个url被爬虫忽略掉了,然后一切都关闭了,因为我们只给爬虫提供了一个 url 链接。同样的请求在网页浏览器里运行正常,即使是在没有会话(session)历史的隐匿模式也可以,所以这一定是由于两者请求头信息的差异造成的。我们可以使用 tcpdump 来比较这两个请求的头信息,但其实有个常见错误,所以我们应该首先检查: user agent 。
Scrapy 默认把 user-agent 设置为 “Scrapy/1.3.3 (+http://scrapy.org)“,一些服务器可能会屏蔽这样的请求,甚至使用白名单只允许少量的user agent 通过。你可以在线查看 最常见的 user agent ,使用其中任何一个通常就足以绕过基本反爬虫策略。选择一个你最喜欢的 User-agent ,然后打开 zipru_scraper/settings.py
,替换 User agent
使用下面内容替换 USER_AGENT :
你可能注意到了,默认的scrapy设置中有一些令爬虫蒙羞的事。关于这个问题的观点众说纷纭,但是我个人认为假如你想让爬虫表现的像是一个人在使用普通的网页浏览器,那么你就应该把你的爬虫设置地像普通的网络浏览器那样。所以让我们一起添加下面的设置来降低一下爬虫响应速度:
通过 AutoThrottle 扩展 ,上面的设置会创建一个稍微真实一点的浏览模式。我们的爬虫在默认情况下会遵守 robots.txt
,所以现在我们的行为非常检点。
现在使用 scrapy crawl zipru -o torrents.jl
命令再次运行爬虫,应该会产生下面的输出:
这是一个巨大的进步!我们获得了两个 200
状态码和一个 302
状态码,下载中间件知道如何处理 302
状态码。不幸的是,这个 302
将我们的请求重定向到了一个看起来不太吉利的页面 threat_defense.php
。不出所料,爬虫没有发现任何有用的东西,然后爬虫就停止运行了。
注: 假如网站检测到你的爬虫,那么网站就会把你的请求重定向到 threat_defense.php 页面,使你的爬虫失效,用来防止频繁的爬虫请求影响了网站正常用户的使用。
下载中间件
在我们深入研究我们目前所面临的更复杂的问题之前,先了解一下请求和响应在爬虫中是怎样被处理的,将会很有帮助。当我们创建了我们基本的爬虫,我们生成了一个 scrapy.Request
对象,然后这些请求会以某种方法转化为与服务器的响应相对应的 scrapy.Response
对象。这里的 “某种方法” 很大一部分是来自于下载中间件。
下载中间件继承自 scrapy.downloadermiddlewares.DownloaderMiddleware
类并且实现了 process_request(request, spider)
和 process_response(request, response, spider)
方法。你大概可以从他们的名字中猜到他们是做什么的。实际上这里有一大堆的默认开启的中间件。下面是标准的中间件配置(你当然可以禁用、添加或是重新设置这些选项):
当一个请求到达服务器时,他们会通过每个这些中间件的 process_request(request, spider)
方法。 这是按照数字顺序发生的,RobotsTxtMiddleware
中间件首先产生请求,并且 HttpCacheMiddleware
中间件最后产生请求。一旦接收到一个响应,它就会通过任何已启用的中间件的 process_response(request,response,spider)
方法来返回响应。这次是以相反的顺序发生的,所以数字越高越先发送到服务器,数字越低越先被爬虫获取到。
一个特别简单的中间件是 CookiesMiddleware
。它简单地检查响应中请求头的 Set-Cookie
,并且保存 cookie 。然后当响应返回的时候,他们会适当地设置 Cookie
请求头标记,这样这些标记就会被包含在发出的请求中了。这个由于时间太久的原因要比我们说的要稍微复杂些,但你会明白的。
另一个相对基本的就是 RedirectMiddleware
中间件,它是用来处理 3XX
重定向的。它让一切不是 3XX
状态码的响应都能够成功的通过,但假如响应中还有重定向发生会怎样? 唯一能够弄清楚服务器如何响应重定向URL的方法就是创建一个新的请求,而且这个中间件就是这么做的。当 process_response(request, response, spider)
方法返回一个请求对象而不是响应对象的时候,那么当前响应就会被丢弃,一切都会从新的请求开始。这就是 RedirectMiddleware
中间件怎样处理重定向的,这个功能我们稍后会用到。
如果你对于有那么多的中间件默认是开启的感到惊讶的话,那么你可能有兴趣看看 体系架构概览。实际上同时还有很多其他的事情在进行,但是,再说一次,scrapy的最大优点之一就是你不需要知道它的大部分原理。你甚至不需要知道下载中间件的存在,却能写一个实用的爬虫,你不必知道其他部分就可以写一个实用的下载中间件。
困难的问题
回到我们的爬虫上来,我们发现我们被重定向到某个 threat_defense.php?defense=1&...
URL上,而不是我们要找的页面。当我们在浏览器里面访问这个页面的时候,我们看到下面的东西停留了几秒:
在被重定向到 threat_defense.php?defense=2&...
页面之前,会出现像下面的提示:
看看第一个页面的源代码就会发现,有一些 javascript 代码负责构造一个特殊的重定向URL,并且构造浏览器的cookies。如果我们想要完成这个任务,那我们就必须同时解决上面这两个问题。
接下来,当然我们也需要解决验证码并提交答案。如果我们碰巧弄错了,那么我们有时会被重定向到另一个验证码页面,或者我们会在类似于下面的页面上结束访问:
在上面的页面中,我们需要点击 “Click here” 链接来开始整个重定向的循环,小菜一碟,对吧?
我们所有的问题都源于最开始的 302
重定向,因此处理它们的方法自然而然应该是做一个自定义的 重定向中间件。我们想让我们的中间件在所有情况下都像是正常重定向中间件一样,除非有一个 302
状态码并且请求被重定向到 threat_defense.php
页面。当它遇到特殊的 302
状态码时,我们希望它能够绕过所有的防御机制,把访问cookie添加到 session 会话中,最后重新请求原来的页面。如果我们能够做到这一点,那么我们的Spider类就不必知道这些事情,因为请求会全部成功。
打开 zipru_scraper/middlewares.py
文件,并且把内容替换成下面的代码:
你可能注意到我们继承了 RedirectMiddleware
类,而不是直接继承 DownloaderMiddleware
类。这样就允许我们重用大部分的重定向处理函数,并且把我们的代码插入到 _redirect(redirected, request, spider, reason)
函数中,一旦有重定向的请求被创建,process_response(request, response, spider)
函数就会调用这个函数。我们只是把对于普通的重定向的处理推迟到父类进行处理,但是对于特殊的威胁防御重定向的处理是不一样的。我们到目前为止还没有实现 bypass_threat_defense(url)
方法,但是我们可以知道它应该返回访问cookies,并把它附加到原来的请求中,然后原来的请求将被重新处理。
为了开启我们新的中间件,我们需要把下面的内容添加到 zipru_scraper/settings.py
中:
这会禁用默认的重定向中间件,并且把我们的中间件添加在中间件堆栈中和默认重定向中间件相同的位置。我们必须安装一些额外的包,虽然我们现在没有用到,但是稍后我们会导入它们:
请注意,这三个包都有 pip 无法处理的外部依赖,如果你运行出错,那么你可能需要访问 dryscrape, Pillow, 和 pytesseract 的安装教程,遵循平台的具体说明来解决。
我们的中间件现在应该能够替代原来的标准重定向中间件,现在我们只需要实现 bypass_thread_defense(url)
方法。我们可以解析 javascript 代码来得到我们需要的变量,然后用 python 重建逻辑,但这看起来很不牢靠,而且需要大量的工作。让我们采用更简单的方法,尽管可能还是比较笨重,使用无头的 webkit 实例。有几个不同选择,但我个人比较喜欢 dryscrape (我们已经在上面安装了)
首先,让我们在中间件构造函数中初始化一个 dryscrape 会话。
你可以把这个会话对象当做是一个单独的浏览器标签页,它可以完成一切浏览器通常可以做的事情(例如:获取外部资源,执行脚本)。我们可以在新的标签页中打开新的 URL 链接,点击一些东西,或者在输入框中输入内容,或是做其他的各种事情。Scrapy 支持并发请求和多项处理,但是响应的处理是单线程的。这意味着我们可以使用这个单独的 dryscrapy 会话,而不必担心线程安全。
现在让我们实现绕过威胁防御机制的基本逻辑。
这样就处理了我们在浏览器中遇到的所有不同的情况,并且完全符合人类在每种情况中的行为。在任何给定情况下采取的措施都取决于当前页面的情况,所以这种方法可以稍微优雅一点地处理各种不同的情况。
最后一个难题是如果如何解决验证码。网上提供了 验证码识别 服务,你可以在必要时使用它的API,但是这次的这些验证码非常简单,我们只用 OCR 就可以解决它。使用 pytessertact 的 OCR 功能,最后我们可以添加 solve_captcha(img)
函数,这样就完善了 bypass_threat_defense()
函数。
你可能注意到如果验证码因为某些原因识别失败的话,它就会委托给 back to the bypass_threat_defense()
函数。这样就给了我们多次识别验证码的机会,但重点是,我们会在得到正确结果之前一直在验证码识别过程中循环。
这应该足够让我们的爬虫工作,但是它有可能陷入死循环中。
至少看起来我们的中间件已经成功地解决了验证码,然后补发了请求。问题在于,新的请求再次触发了威胁防御机制。我第一个想法是我可能在怎样解析或是添加cookie上面有错误,但是我检查了三次,代码是正确的。这是另外一种情况 “唯一可能不同的事情就是请求头” 。
很明显,scrapy 和 dryscrape 的请求头都绕过了最初的触发 403
响应的过滤器,因为我们现在不会得到任何 403
的响应。这肯定是因为它们的请求头信息不一致导致的。我的猜测是其中一个加密的访问cookies包含了整个请求头信息的散列值,如果这个散列不匹配,就会触发威胁防御机制。这样的目的可能是防止有人把浏览器的cookie复制到爬虫中去,但是它只是增加了你需要解决的问题而已。
所以让我们在 zipru_scraper/settings.py
中把请求头信息修改成下面这个样子。
注意我们已经把 User-Agent
头信息修改成了我们之前定义的 USER_AGENT
中去.这个工作是由 user agent 中间件自动添加进去的,但是把所有的这些配置放到一个地方可以使得 dryscrape 更容易复制请求头信息。我们可以通过修改 ThreatDefenceRedirectMiddleware
初始化函数像下面这样:
现在,当我们可以通过命令 scrapy crawl zipru -o torrents.jl
再次运行爬虫。我们可以看到源源不断的爬取的内容,并且我们的 torrents.jl
文件记录把爬取的内容全部记录了下来。我们已经成功地绕过了所有的威胁防御机制。
总结
我们已经成功地写了一个能够解决四种截然不同的威胁防御机制的爬虫,这四种防御机制分别是:
User agent 过滤
模糊的 Javascript 重定向
验证码
请求头一致性检查
我们的目标网站 Zipru 可能是虚构的,但是这些机制都是你会在真实网站上遇到的真实的反爬虫技术。
加vx:tanzhouyiwan或qq群813622576免费领取学习资料
你可能感兴趣的:(Python,编程语言,爬虫)
大神教你用Python实现Wake On Lan远程开机功能
云计算运维工程师
技术干活
这篇文章主要介绍了使用Python实现WakeOnLan远程开机功能,文中给大家补充介绍了python通过wakeonlan唤醒内网电脑开机,非常不错,感兴趣的朋友跟随小编一起学习吧Wake-On-LAN简称WOL,是一种电源管理功能;如果存在网络活动,则允许设备将操作系统从待机或休眠模式中唤醒。许多主板厂商支持IBM提出的网络唤醒标准。该标准允许网络管理员远程打开PC机电源,以便进行文件升级、资
Python程序中对文件名后缀为.pickle 的文件认识、创建和读取介绍和程序举例
qq_18937049
Python python pickle
Python程序中对文件名后缀为.pickle的文件认识、创建和读取介绍和程序举例目录Python程序中对文件名后缀为.pickle的文件认识、创建和读取介绍和程序举例1..pickle文件概述2..pickle文件的特点2.1序列化对象2.2二进制格式2.3兼容性3.创建和读取.pickle文件3.1创建.pickle文件——pickle.dump()3.2从.pickle文件读取——pickl
PyWakeOnLan:Python 实现的轻量级 Wake-on-LAN 工具
郁虹宝Lucille
PyWakeOnLan:Python实现的轻量级Wake-on-LAN工具pywakeonlanAsmallpythonmoduleforwakeonlan.项目地址:https://gitcode.com/gh_mirrors/py/pywakeonlan项目基础介绍与编程语言PyWakeOnLan是一个由RemcoHaszing开发的小巧且易于使用的Python模块,专门用于实现Wake-on
3D U-Net CNN医学图像分割项目教程
尤辰城Agatha
3DU-NetCNN医学图像分割项目教程3DUnetCNNPytorch3DU-NetConvolutionNeuralNetwork(CNN)designedformedicalimagesegmentation项目地址:https://gitcode.com/gh_mirrors/3d/3DUnetCNN1.项目介绍3DU-NetCNN是由Ellisdg开发的Python实现,专门用于医学图像
开源项目PyWakeOnLan常见问题解答
李申山
开源项目PyWakeOnLan常见问题解答pywakeonlanAsmallpythonmoduleforwakeonlan.项目地址:https://gitcode.com/gh_mirrors/py/pywakeonlan项目基础介绍PyWakeOnLan是一个轻量级的Python模块,用于实现Wake-on-LAN(WOL)功能。通过这个工具,开发者可以方便地发送魔包信号来远程唤醒支持WOL
目前主流游戏引擎的分析报告
游戏开发88
cocoscreator unity 游戏引擎
前言游戏引擎之争就像编程语言之争一样,在游戏开发圈永远是一个火爆的话题,目前市面上主流的一些游戏引擎,我们来给他们做一些比较,了解他们的历史,特点,为了严谨,备注一下写这个文章的时间编写时间是2021年4月20日。目前国内主流在用的游戏引擎有,Unity,Cocos,Laya,UE4,白鹭,接下来我们一起来分析这些引擎的特点。1:国民3D引擎UnityUnity,使用C#或Lua语言开发。国民3D
华为OD机试E卷 - 机器人活动区域(Java & Python& JS & C++ & C )
算法大师
最新华为OD机试 java 华为od 机器人 c语言 javascript python 华为OD机试E卷
最新华为OD机试真题目录:点击查看目录华为OD面试真题精选:点击立即查看题目描述现有一个机器人,可放置于M×N的网格中任意位置,每个网格包含一个非负整数编号,当相邻网格的数字编号差值的绝对值小于等于1时,机器人可以在网格间移动。问题:求机器人可活动的最大范围对应的网格点数目。说明:网格左上角坐标为(0,0),右下角坐标为(m−1,n−1),机器人只能在相邻网格间上下左右移动输入描述第1行输入为M和
Python基础03(循环与选择结构)
XYX的Blog
Python python 数据结构 开发语言
Python循环与选择结构1.条件表达式绝大部分合法的Python表达式都可以作为条件表达式。在python中除了False,0,0.0,0j,None,空列表,空元组,空集合,空字典,空字符串,空range对象,其余的都与True等价函数,生成器对象都等价于True2.选择结构Python的分支控制语句,即根据表达式的判断结果,为True还是为False,选择运行程序的其中一个分支。Python
Python学习笔记 | 类与对象
MUYUN友逹
Python学习笔记 类与对象
基于Python3版本的学习。初识概念:类(class)与对象(object)生活中我们所说的类,是物以类聚的类,是分门别类的类,是多个类似事物组成的群体的统称。而在Python中我们所遇到的类(class),比如整数、字符串、浮点数等,不同的数据类型就属于不同的类。准确来说,它们的全名是整数类、字符串类、浮点数类。每一个类之下都包含无数相似的不同个例。在Python的术语里,我们把类的个例就叫做
如何使用JavaScript开发AR(增强现实)移动应用 (一)
Python中的class体内定义方法时,如果没有显式地包含self参数,有时候依然可以被调用。这是一个非常有趣的话题,因为它涉及到对Python中类与对象之间关系的更深理解。要理解为什么这种情况下方法依然能够被调用,我们需要逐步拆解Python类的构造方式以及方法绑定的原理。
C语言与数据库交互的实用指南
GSAHSHASH
c语言 数据库 交互
在软件开发中,数据库是存储、检索和管理数据的重要工具。而C语言,作为一种高效、底层的编程语言,也常常需要与数据库进行交互。本文将为你提供一份关于C语言与数据库交互的实用指南,帮助你更好地理解如何在C程序中操作数据库。1.数据库基础知识在开始之前,我们需要对数据库有一些基本的了解。数据库是一个按照数据结构来组织、存储和管理数据的仓库,它通常包括多个数据表,每个数据表又包含多个字段和记录。常见的数据库
Python语言的数据类型
疯狂小小小码农
包罗万象 golang 开发语言 后端
Python中的数据类型详解Python是一种多用途的编程语言,以其简单易学的语法受到广泛欢迎。为了有效地处理和表示不同类型的数据,Python为程序员提供了多种数据类型。本文将深入探讨Python中的基本数据类型、复合数据类型、标准库中的数据类型以及各类型之间的转换。一、基本数据类型1.整数(int)整数(int)是Python中的一种基本数据类型,表示没有小数部分的整数。Python中的整数可
Python语言的计算机基础
疯狂小小小码农
包罗万象 golang 开发语言 后端
Python语言的计算机基础绪论在当今信息技术飞速发展的时代,编程已经成为了一种必备技能。Python凭借其简洁、易读和强大的功能,逐渐成为初学者学习编程的首选语言。本文将以Python语言为基础,探讨计算机科学的基本概念,并帮助读者更好地理解计算机的工作原理以及如何利用Python进行编程。一、Python简介Python是一种高级编程语言,由荷兰人GuidovanRossum于1991年首次发
MATLAB语言的计算机基础
疯狂小小小码农
包罗万象 golang 开发语言 后端
MATLAB语言的计算机基础引言在当今信息技术飞速发展的时代,编程能力已成为当代人士必备的一项基本技能。MATLAB(矩阵实验室)作为一种高级编程语言和环境,广泛应用于数据分析、算法开发、模型创建、数字图像处理和计算机视觉等多个领域。MATLAB以其强大的矩阵运算和可视化能力,成为了科研人员和工程师的重要工具,尤其在数学、物理、工程等学科中,它的应用不可或缺。本文将从MATLAB的基本概念、环境搭
JavaScript语言的计算机基础
疯狂小小小码农
包罗万象 golang 开发语言 后端
JavaScript语言的计算机基础引言自1995年由网景公司(Netscape)推出以来,JavaScript已经从一个简单的客户端脚本语言发展成为一种广泛使用的编程语言。如今,它不仅在网页开发中扮演着不可或缺的角色,还成为后端开发、移动应用开发、甚至桌面应用开发的一部分。在本文中,我们将探讨JavaScript语言的基本概念及其背后的计算机基础,以帮助读者更好地理解这种语言及其应用。一、计算机
Windows 11安装DeepSpeed报错(Unable to pre-compile async_io)问题解决
happy coding
windows gpt
Windows11安装DeepSpeed报错(Unabletopre-compileasync_io)问题解决报错如下Preparingmetadata(setup.py)...errorerror:subprocess-exited-with-error×pythonsetup.pyegg_infodidnotrunsuccessfully.│exitcode:1╰─>[17linesofout
用Python做一个网页
我是学习编程的人 多多照顾我吧求你
python
要用Python做一个网页,你可以使用Flask或Django这样的Web框架。这里以Flask为例,给出一个简单的示例:1.首先,确保你已经安装了Flask。如果没有,可以使用以下命令安装:```bashpipinstallflask```2.创建一个名为`app.py`的文件,并在其中编写以下代码:```pythonfromflaskimportFlask,render_templateapp
华为OD机试E卷 --堆栈中的剩余数字--24年OD统一考试(Java & JS & Python & C & C++)
飞码创造者
最新华为OD机试题库2024 java 华为od javascript python js c语言
文章目录题目描述输入描述输出描述用例题目解析JS算法源码Java算法源码python算法源码c算法源码题目描述向一个空栈中依次存入正整数,假设入栈元素n(1<=n<=2^31-1)按顺序依次为nx…n4、n3、n2、n1,每当元素入栈时,如果n1=n2+…+ny(y的范围[2,x],1<=x<=1000),则n1~ny全部元素出栈,重新入栈新元素m(m=2n1)。如:依次向栈存入6、1、2、3,当
华为OD机试E卷 --机器人活动区域--24年OD统一考试(Java & JS & Python & C & C++)
飞码创造者
最新华为OD机试题库2024 华为od 机器人 java javascript python js
文章目录题目描述输入描述输出描述用例题目解析JS算法源码Java算法源码python算法源码c算法源码c++算法源码题目描述现有一个机器人,可放置于M×N的网格Q中任意位置,每个网格包含一个非负整数编号。当相邻网格的数字编号差值的绝对值小于等于1时,机器人可在网格间移动问题:求机器人可活动的最大范围对应的网格点数目。说明:1)网格左上角坐标为(0,0),右下角坐标为(m-1,n-1)2)机器人只能
Python 爬虫实战案例 - 获取社交平台事件热度并进行影响分析
西攻城狮北
Python实用案例 python 爬虫 事件热度 影响分析
目录一、引言二、数据爬取三、数据分析四、可视化展示五、总结一、引言在当今信息爆炸的时代,社交平台成为了各类事件发酵和传播的重要场所。了解社交平台上事件的热度以及其潜在影响,对于舆情监测、市场营销、社会趋势分析等领域具有重要意义。本文将通过一个实际案例,展示如何使用Python爬虫技术获取社交平台上特定事件的相关数据,并对其热度和影响进行深入分析。在本篇博客中,我们将学习如何使用Python编写一个
Python编程与在线医疗平台数据挖掘与数据应用交互性研究
Allen_LVyingbo
数智化医院2025 python 数据挖掘
一、引言1.1研究背景与意义在互联网技术飞速发展的当下,在线医疗平台如雨后春笋般涌现,为人们的就医方式带来了重大变革。这些平台打破了传统医疗服务在时间和空间上的限制,使患者能够更加便捷地获取医疗资源。据相关报告显示,中国基于互联网的医疗保健行业已进入新的发展阶段,2023年中国在线医疗服务增长显著,高质量医院和在线医疗平台取得了长足进步,在线医疗的用户规模也在持续扩大,其中在线咨询服务的用户占比较
C语言的数据库交互
疯狂小小小码农
包罗万象 golang 开发语言 后端
C语言的数据库交互引言在现代的软件开发中,数据库是应用程序的重要组成部分。无论是小型的个人项目还是大型的企业级应用,数据的存储、查询和管理都需要有效的数据库系统。在众多编程语言中,C语言以其高效、灵活和底层操作的特性,被广泛应用于系统编程、嵌入式开发等领域。当然,C语言在数据库交互方面也是非常强大的。本文将深入探讨C语言与数据库的交互,包括常用的数据库及其驱动,数据库操作的基本流程,常见的数据库操
python封装程序Failed to execute script pyi_rth_multiprocessing错误
星烨无痕
pyinstaller封装程序 机器学习 人工智能 python
我的python程序编写环境为win10、python3.8.6,打包成exe文件后,在win10中能正常打开,没有任何问题。将程序拷贝到另一台电脑,电脑使用的是win7系统,运行程序出现Failedtoexecutescriptpyi_rth_multiprocessing错误,错误显示如下:Traceback(mostrecentcalllast):File"C:\Users\wuhen\Ap
PyTorch机器学习与深度学习技术方法
Teacher.chenchong
机器学习 python 开发语言
近年来,随着AlphaGo、无人驾驶汽车、医学影像智慧辅助诊疗、ImageNet竞赛等热点事件的发生,人工智能迎来了新一轮的发展浪潮。尤其是深度学习技术,在许多行业都取得了颠覆性的成果。另外,近年来,Pytorch深度学习框架受到越来越多科研人员的关注和喜爱。Python基础知识串讲1、Python环境搭建(Python软件下载、安装与版本选择;PyCharm下载、安装;Python之HelloW
深度学习模块C2f代码详解
你是狒狒吗
目标检测 人工智能 计算机视觉 pytorch YOLO 神经网络
C2f是一个用于构建卷积神经网络(CNN)的模块,特别是在YOLOv5和YOLOv8等目标检测模型中。这个模块是一个改进的CSP(CrossStagePartial)Bottleneck结构,旨在提高计算效率和特征提取能力。下面是对C2f类的详细解释:类定义和初始化Python复制classC2f(nn.Module):“”“FasterImplementationofCSPBottleneckw
python多线程锁_python:线程,多线程锁,多线程递归锁
八亿中产
python多线程锁
#!usr/bin/envpython#-*-coding:utf-8-*-__author__="Samson"importthreading,timedefrun(n):print("task",n)time.sleep(2)print("currentthread:",threading.current_thread())#当前线程t_obj=[]#存线程实例start_time=time.
python线条加粗_python 加粗
weixin_39765057
python线条加粗
广告关闭腾讯云11.11云上盛惠,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高返5000元!背景知识:docx文件的结构分为三层,1、docment对象表示整个文档;2、docment包含了paragraph对象的列表,每个paragraph对象用来表示文档中的一个段落;3、一个paragraph对象包含run对象的列表,一个run对象就是style相同的一段文本。问题描述:
python读取word指定内容_Python-docx 读取word.docx内容
weixin_39636176
第一次写博客,也不知道要写点儿什么好,所以就把我在学习Python的过程中遇到的问题记录下来,以便之后查看,本人小白,写的不好,如有错误,还请大家批评指正!中文编码问题总是让人头疼,想要用Python读取word中的内容,用open()经常报错,上网一搜结果发现了Python有专门读取.docx的模块python_docx(只能读取.docx文件,不能读取.doc文件),用起来很方便。安装pyth
day39——多线程实例、多线程锁
weixin_33953384
java python
python的锁可以独立提取出来1mutex=threading.Lock()2#锁的使用3#创建锁4mutex=threading.Lock()5#锁定6mutex.acquire([timeout])7#释放8mutex.release()概念资源加锁其实并不是给资源加锁,而是用锁去锁定资源,你可以定义多个锁,像下面的代码,当你需要独占某一资源时,任何一个锁都可以锁这个资源就好比你用不同的锁都
python多线程锁实战_Python多线程锁
7Nut7
python多线程锁实战
在多线程程序执行过程中,为什么需要给一些线程加锁以及如何加锁,下面就来说一说。1.给线程加锁的原因我们知道,不同进程之间的内存空间数据是不能够共享的,试想一下,如果可以随意共享,谈何安全?但是一个进程中的多个线程是可以共享这个进程的内存空间中的数据的,比如多个线程可以同时调用某一内存空间中的某些数据(只是调用,没有做修改)。试想一下,在某一进程中,内存空间中存有一个变量对象的值为num=8,假如某
VMware Workstation 11 或者 VMware Player 7安装MAC OS X 10.10 Yosemite
iwindyforest
vmware mac os 10.10 workstation player
最近尝试了下VMware下安装MacOS 系统,
安装过程中发现网上可供参考的文章都是VMware Workstation 10以下, MacOS X 10.9以下的文章,
只能提供大概的思路, 但是实际安装起来由于版本问题, 走了不少弯路, 所以我尝试写以下总结, 希望能给有兴趣安装OSX的人提供一点帮助。
写在前面的话:
其实安装好后发现, 由于我的th
关于《基于模型驱动的B/S在线开发平台》源代码开源的疑虑?
deathwknight
JavaScript java 框架
本人从学习Java开发到现在已有10年整,从一个要自学 java买成javascript的小菜鸟,成长为只会java和javascript语言的老菜鸟(个人邮箱:
[email protected] )
一路走来,跌跌撞撞。用自己的三年多业余时间,瞎搞一个小东西(基于模型驱动的B/S在线开发平台,非MVC框架、非代码生成)。希望与大家一起分享,同时有许些疑虑,希望有人可以交流下
平台
如何把maven项目转成web项目
Kai_Ge
maven MyEclipse
创建Web工程,使用eclipse ee创建maven web工程 1.右键项目,选择Project Facets,点击Convert to faceted from 2.更改Dynamic Web Module的Version为2.5.(3.0为Java7的,Tomcat6不支持). 如果提示错误,可能需要在Java Compiler设置Compiler compl
主管???
Array_06
工作
转载:http://www.blogjava.net/fastzch/archive/2010/11/25/339054.html
很久以前跟同事参加的培训,同事整理得很详细,必须得转!
前段时间,公司有组织中高阶主管及其培养干部进行了为期三天的管理训练培训。三天的课程下来,虽然内容较多,因对老师三天来的课程内容深有感触,故借着整理学习心得的机会,将三天来的培训课程做了一个
python内置函数大全
2002wmj
python
最近一直在看python的document,打算在基础方面重点看一下python的keyword、Build-in Function、Build-in Constants、Build-in Types、Build-in Exception这四个方面,其实在看的时候发现整个《The Python Standard Library》章节都是很不错的,其中描述了很多不错的主题。先把Build-in Fu
JSP页面通过JQUERY合并行
357029540
JavaScript jquery
在写程序的过程中我们难免会遇到在页面上合并单元行的情况,如图所示
如果对于会的同学可能很简单,但是对没有思路的同学来说还是比较麻烦的,提供一下用JQUERY实现的参考代码
function mergeCell(){
var trs = $("#table tr");
&nb
Java基础
冰天百华
java基础
学习函数式编程
package base;
import java.text.DecimalFormat;
public class Main {
public static void main(String[] args) {
// Integer a = 4;
// Double aa = (double)a / 100000;
// Decimal
unix时间戳相互转换
adminjun
转换 unix 时间戳
如何在不同编程语言中获取现在的Unix时间戳(Unix timestamp)? Java time JavaScript Math.round(new Date().getTime()/1000)
getTime()返回数值的单位是毫秒 Microsoft .NET / C# epoch = (DateTime.Now.ToUniversalTime().Ticks - 62135
作为一个合格程序员该做的事
aijuans
程序员
作为一个合格程序员每天该做的事 1、总结自己一天任务的完成情况 最好的方式是写工作日志,把自己今天完成了什么事情,遇见了什么问题都记录下来,日后翻看好处多多
2、考虑自己明天应该做的主要工作 把明天要做的事情列出来,并按照优先级排列,第二天应该把自己效率最高的时间分配给最重要的工作
3、考虑自己一天工作中失误的地方,并想出避免下一次再犯的方法 出错不要紧,最重
由html5视频播放引发的总结
ayaoxinchao
html5 视频 video
前言
项目中存在视频播放的功能,前期设计是以flash播放器播放视频的。但是现在由于需要兼容苹果的设备,必须采用html5的方式来播放视频。我就出于兴趣对html5播放视频做了简单的了解,不了解不知道,水真是很深。本文所记录的知识一些浅尝辄止的知识,说起来很惭愧。
视频结构
本该直接介绍html5的<video>的,但鉴于本人对视频
解决httpclient访问自签名https报javax.net.ssl.SSLHandshakeException: sun.security.validat
bewithme
httpclient
如果你构建了一个https协议的站点,而此站点的安全证书并不是合法的第三方证书颁发机构所签发,那么你用httpclient去访问此站点会报如下错误
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path bu
Jedis连接池的入门级使用
bijian1013
redis redis数据库 jedis
Jedis连接池操作步骤如下:
a.获取Jedis实例需要从JedisPool中获取;
b.用完Jedis实例需要返还给JedisPool;
c.如果Jedis在使用过程中出错,则也需要还给JedisPool;
packag
变与不变
bingyingao
不变 变 亲情永恒
变与不变
周末骑车转到了五年前租住的小区,曾经最爱吃的西北面馆、江西水饺、手工拉面早已不在,
各种店铺都换了好几茬,这些是变的。
三年前还很流行的一款手机在今天看起来已经落后的不像样子。
三年前还运行的好好的一家公司,今天也已经不复存在。
一座座高楼拔地而起,
【Scala十】Scala核心四:集合框架之List
bit1129
scala
Spark的RDD作为一个分布式不可变的数据集合,它提供的转换操作,很多是借鉴于Scala的集合框架提供的一些函数,因此,有必要对Scala的集合进行详细的了解
1. 泛型集合都是协变的,对于List而言,如果B是A的子类,那么List[B]也是List[A]的子类,即可以把List[B]的实例赋值给List[A]变量
2. 给变量赋值(注意val关键字,a,b
Nested Functions in C
bookjovi
c closure
Nested Functions 又称closure,属于functional language中的概念,一直以为C中是不支持closure的,现在看来我错了,不过C标准中是不支持的,而GCC支持。
既然GCC支持了closure,那么 lexical scoping自然也支持了,同时在C中label也是可以在nested functions中自由跳转的
Java-Collections Framework学习与总结-WeakHashMap
BrokenDreams
Collections
总结这个类之前,首先看一下Java引用的相关知识。Java的引用分为四种:强引用、软引用、弱引用和虚引用。
强引用:就是常见的代码中的引用,如Object o = new Object();存在强引用的对象不会被垃圾收集
读《研磨设计模式》-代码笔记-解释器模式-Interpret
bylijinnan
java 设计模式
声明: 本文只为方便我个人查阅和理解,详细的分析以及源代码请移步 原作者的博客http://chjavach.iteye.com/
package design.pattern;
/*
* 解释器(Interpreter)模式的意图是可以按照自己定义的组合规则集合来组合可执行对象
*
* 代码示例实现XML里面1.读取单个元素的值 2.读取单个属性的值
* 多
After Effects操作&快捷键
cherishLC
After Effects
1、快捷键官方文档
中文版:https://helpx.adobe.com/cn/after-effects/using/keyboard-shortcuts-reference.html
英文版:https://helpx.adobe.com/after-effects/using/keyboard-shortcuts-reference.html
2、常用快捷键
Maven 常用命令
crabdave
maven
Maven 常用命令
mvn archetype:generate
mvn install
mvn clean
mvn clean complie
mvn clean test
mvn clean install
mvn clean package
mvn test
mvn package
mvn site
mvn dependency:res
shell bad substitution
daizj
shell 脚本
#!/bin/sh
/data/script/common/run_cmd.exp 192.168.13.168 "impala-shell -islave4 -q 'insert OVERWRITE table imeis.${tableName} select ${selectFields}, ds, fnv_hash(concat(cast(ds as string), im
Java SE 第二讲(原生数据类型 Primitive Data Type)
dcj3sjt126com
java
Java SE 第二讲:
1. Windows: notepad, editplus, ultraedit, gvim
Linux: vi, vim, gedit
2. Java 中的数据类型分为两大类:
1)原生数据类型 (Primitive Data Type)
2)引用类型(对象类型) (R
CGridView中实现批量删除
dcj3sjt126com
PHP yii
1,CGridView中的columns添加
array(
'selectableRows' => 2,
'footer' => '<button type="button" onclick="GetCheckbox();" style=&
Java中泛型的各种使用
dyy_gusi
java 泛型
Java中的泛型的使用:1.普通的泛型使用
在使用类的时候后面的<>中的类型就是我们确定的类型。
public class MyClass1<T> {//此处定义的泛型是T
private T var;
public T getVar() {
return var;
}
public void setVa
Web开发技术十年发展历程
gcq511120594
Web 浏览器 数据挖掘
回顾web开发技术这十年发展历程:
Ajax
03年的时候我上六年级,那时候网吧刚在小县城的角落萌生。传奇,大话西游第一代网游一时风靡。我抱着试一试的心态给了网吧老板两块钱想申请个号玩玩,然后接下来的一个小时我一直在,注,册,账,号。
彼时网吧用的512k的带宽,注册的时候,填了一堆信息,提交,页面跳转,嘣,”您填写的信息有误,请重填”。然后跳转回注册页面,以此循环。我现在时常想,如果当时a
openSession()与getCurrentSession()区别:
hetongfei
java DAO Hibernate
来自 http://blog.csdn.net/dy511/article/details/6166134
1.getCurrentSession创建的session会和绑定到当前线程,而openSession不会。
2. getCurrentSession创建的线程会在事务回滚或事物提交后自动关闭,而openSession必须手动关闭。
这里getCurrentSession本地事务(本地
第一章 安装Nginx+Lua开发环境
jinnianshilongnian
nginx lua openresty
首先我们选择使用OpenResty,其是由Nginx核心加很多第三方模块组成,其最大的亮点是默认集成了Lua开发环境,使得Nginx可以作为一个Web Server使用。借助于Nginx的事件驱动模型和非阻塞IO,可以实现高性能的Web应用程序。而且OpenResty提供了大量组件如Mysql、Redis、Memcached等等,使在Nginx上开发Web应用更方便更简单。目前在京东如实时价格、秒
HSQLDB In-Process方式访问内存数据库
liyonghui160com
HSQLDB一大特色就是能够在内存中建立数据库,当然它也能将这些内存数据库保存到文件中以便实现真正的持久化。
先睹为快!
下面是一个In-Process方式访问内存数据库的代码示例:
下面代码需要引入hsqldb.jar包 (hsqldb-2.2.8)
import java.s
Java线程的5个使用技巧
pda158
java 数据结构
Java线程有哪些不太为人所知的技巧与用法? 萝卜白菜各有所爱。像我就喜欢Java。学无止境,这也是我喜欢它的一个原因。日常
工作中你所用到的工具,通常都有些你从来没有了解过的东西,比方说某个方法或者是一些有趣的用法。比如说线程。没错,就是线程。或者确切说是Thread这个类。当我们在构建高可扩展性系统的时候,通常会面临各种各样的并发编程的问题,不过我们现在所要讲的可能会略有不同。
开发资源大整合:编程语言篇——JavaScript(1)
shoothao
JavaScript
概述:本系列的资源整合来自于github中各个领域的大牛,来收藏你感兴趣的东西吧。
程序包管理器
管理javascript库并提供对这些库的快速使用与打包的服务。
Bower - 用于web的程序包管理。
component - 用于客户端的程序包管理,构建更好的web应用程序。
spm - 全新的静态的文件包管
避免使用终结函数
vahoa.ma
java jvm C++
终结函数(finalizer)通常是不可预测的,常常也是很危险的,一般情况下不是必要的。使用终结函数会导致不稳定的行为、更差的性能,以及带来移植性问题。不要把终结函数当做C++中的析构函数(destructors)的对应物。
我自己总结了一下这一条的综合性结论是这样的:
1)在涉及使用资源,使用完毕后要释放资源的情形下,首先要用一个显示的方