Golang 原生实现简单爬虫
了解爬虫基本原理,深入探索爬虫的更多玩法。现在爬虫的热度越来越高,有不少人抱着好奇心和兴趣来学习爬虫,有用 Python、Java、PHP 等等,如果你去网上问,学爬虫最好用什么语言?95% 的人会推荐使用 Python,但其中不少人并不是真正了解 Python 的,大多是网上看了点资料,然后盲目从众的。
为什么要用 Golang 原生实现简单爬虫?
- 使用 Golang 语言,我是想告诉大家,只要了解爬虫原理,不管用什么编程语言,基本上都是可以写出一个爬虫系统的。
- 原生意在不适用第三方库类,为的就是让各位更能理解爬虫的基本原理和逻辑,理解基本原理,那拓展爬虫功能是完全没有问题的。
- 简单爬虫的实现,为了让大家能更快的掌握和了解爬虫,所以不打算写一个很复杂的爬虫系统,这样也更方便那些可能并不是 Golang 程序员的理解。
技术是学无止境的,要想进步,就得尝试新东西并去理解它的核心原理,本场 Chat 您将会学到以下内容:
- Golang 的基本入门;
- 爬虫的基本原理;
- 如何防止浪费爬虫资源;
- 后期遇到的问题和解决方案;
- 正则表达式的运用;
- Golang 文件操作;
- Golang 计时器的简单运用;
- HTTP 请求的了解。
探索技术的路上本应该自己造轮子,即使市面上有再多的选择,自己动手尝试也是必要的。第一次尝试必然会问题众多,但你解决它是一件很有成就感的事情,这样才能带给你更大的进步和更深刻的领悟。
如果感兴趣的不妨一起来实现一下这个简单的爬虫。
其实用 Golang 实现爬虫是很简单是事情,但也分情况,我们这次的文章就分享一种最简单的爬虫实现方式,用到的官方库如下:
import ( "fmt" "io" "io/ioutil" "net/http" "os" "regexp" "strconv" "strings" "time" )
如果你能单单通过这些库就想到该怎么做了,那你就很棒棒了。
为了让程序能一直运行下去,我们首先要有一个源网页,然后不断爬抓记录新的链接,记录的手段有很多,比如存在数据库、通过 Redis 缓存、存在文本文件,最简单的应该就是存在数据库了,这个看你们的技术偏向了。我打算把爬来的链接储存在文本文件里。
首先,了解自己爬抓的目标,我准备爬取所有的 Golang 相关答疑或者文章,然后翻来覆去很多网站都感觉不适合做源网址,然后灵机一动,百度一下:
然后就用这样作为源网址吧:
http://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&tn=39042058_20_oem_dg&wd=golang%E5%AE%9E%E7%8E%B0&oq=golang%2520%25E5%2588%25A0%25E9%2599%25A4%25E6%2595%25B0%25E7%25BB%2584&rsv_pq=d9be28ec0002df1b&rsv_t=8017GWpSLPhDmKilZQ1StC04EVpUAeLEP90NIm%2Bk5pRh5R9o57NHMO8Gaxm1TtSOo%2FvtJj%2B98%2Fsc&rqlang=cn&rsv_enter=1&inputT=3474&rsv_sug3=16&rsv_sug1=11&rsv_sug7=100&rsv_sug2=0&rsv_sug4=4230
有了源网址,那下面的事情只要捋顺就好办了。首先我们为了抓取到链接,需要一个正则表达式:
var ( regHref = `((ht|f)tps?)://[w]{0,3}.baidu.com/link\?[a-zA-z=0-9-\s]*` )
因为这个正则表达式我们后面可能会复用,所以可以存到一个全局变量里。
一个爬虫如果不限制分秒爬抓次数,那你的网络肯定会受不了,如果电脑配置不行的话,电脑也会挂掉,所以我们需要写一个计时器,Golang 已经提供了计时器的包 => time:
func Timer() { t := time.NewTimer(time.Second * 1) <-t.C fmt.Print("\n\n\n执行爬抓\n\n") Timer() }
为什么要写在一个 Timer 函数里?当然是用来调用的。
因为我们存在两种情况,第一次爬取或不是第一次爬取的情况是做不同操作的。那要怎么判断呢?因为我们的链接是储存在 txt 文件里的,所以我们只需要去查 txt 文件是不是为空,如果为空就认为他是第一次执行程序,先访问源网址,否则就按照文件里的链接依次访问。
代码如下:
func main() { if checkFile("./data/", "url.txt").Size() == 0 { fistStart() main() } else { Timer() } }
那我们先看一下 firstStart() 函数,稍后再解释代码:
func fistStart() { var num int url := "http://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&tn=39042058_20_oem_dg&wd=golang%E5%AE%9E%E7%8E%B0&oq=golang%2520%25E5%2588%25A0%25E9%2599%25A4%25E6%2595%25B0%25E7%25BB%2584&rsv_pq=d9be28ec0002df1b&rsv_t=8017GWpSLPhDmKilZQ1StC04EVpUAeLEP90NIm%2Bk5pRh5R9o57NHMO8Gaxm1TtSOo%2FvtJj%2B98%2Fsc&rqlang=cn&rsv_enter=1&inputT=3474&rsv_sug3=16&rsv_sug1=11&rsv_sug7=100&rsv_sug2=0&rsv_sug4=4230" resp, _ := http.Get(url) defer resp.Body.Close() body, _ := ioutil.ReadAll(resp.Body) reg := regexp.MustCompile(`((ht|f)tps?)://[w]{0,3}.baidu.com/link\?[a-zA-z=0-9-\s]*`) f, _ := os.OpenFile("./data/url.txt", os.O_CREATE|os.O_APPEND|os.O_RDWR, 0666) defer f.Close() for _, d := range reg.FindAllString(string(body), -1) { ff, _ := os.OpenFile("./data/url.txt", os.O_RDWR, 0666) file, _ := ioutil.ReadAll(ff) dd := strings.Split(d, "") dddd := "" for _, ddd := range dd { if ddd == "?" { ddd = `\?` } dddd += ddd } if checkRegexp(string(file), dddd, 0).(string) == "" { io.WriteString(f, d+"\n") fmt.Print("\n收集地址:" + d + "\n") num++ } // fmt.Print(string(file)) ff.Close() } fmt.Print("\n首次收集网络地址:" + strconv.Itoa(len(reg.FindAllString(string(body), -1))) + "\n") fmt.Print("\n去重后网络地址数:" + strconv.Itoa(num)) fmt.Print("\n\n首次储存成功!\n") }
其实很简单,就是发起一个 get 请求,然后你会获取到 byte[] 类型的数据,转换成 string 类型之后,就是网页的代码了。
分解一下(了解原理的跳过这段):
url := "http://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&tn=39042058_20_oem_dg&wd=golang%E5%AE%9E%E7%8E%B0&oq=golang%2520%25E5%2588%25A0%25E9%2599%25A4%25E6%2595%25B0%25E7%25BB%2584&rsv_pq=d9be28ec0002df1b&rsv_t=8017GWpSLPhDmKilZQ1StC04EVpUAeLEP90NIm%2Bk5pRh5R9o57NHMO8Gaxm1TtSOo%2FvtJj%2B98%2Fsc&rqlang=cn&rsv_enter=1&inputT=3474&rsv_sug3=16&rsv_sug1=11&rsv_sug7=100&rsv_sug2=0&rsv_sug4=4230" resp, _ := http.Get(url) defer resp.Body.Close() body, _ := ioutil.ReadAll(resp.Body) reg := regexp.MustCompile(`((ht|f)tps?)://[w]{0,3}.baidu.com/link\?[a-zA-z=0-9-\s]*`) f, _ := os.OpenFile("./data/url.txt", os.O_CREATE|os.O_APPEND|os.O_RDWR, 0666) defer f.Close()
这段主要是发起一个 get 网络请求,然后把请求到的 byte 数据转成 stirng 类型的数据,跳过正则获取匹配链接获取一个链接数组(不过分赘述,如果还不懂 http 请求可以另寻百度)。
for _, d := range reg.FindAllString(string(body), -1) { ff, _ := os.OpenFile("./data/url.txt", os.O_RDWR, 0666) file, _ := ioutil.ReadAll(ff) dd := strings.Split(d, "") dddd := "" for _, ddd := range dd { if ddd == "?" { ddd = `\?` } dddd += ddd } if checkRegexp(string(file), dddd, 0).(string) == "" { io.WriteString(f, d+"\n") fmt.Print("\n收集地址:" + d + "\n") num++ } // fmt.Print(string(file)) ff.Close() }
通过循环数组,首先对链接里的特殊符号做特出处理,然后通过 checkRegexp 函数做查重,就是防止有多个重复链接记录导致浪费资源,最后存入 txt 文件。
checkRegexp 函数:
func checkRegexp(cont string, reg string, style int) (result interface{}) { check := regexp.MustCompile(reg) switch style { case 0: result = check.FindString(cont) case 1: result = check.FindAllString(cont, -1) default: result = check.FindAll([]byte(cont), -1) } return }
这里,程序的首次执行已经完成,并可以成功记录爬取的链接了。程序执行如下:
程序首次执行成功后,我们已经成功获取了源页面所提供的链接地址。下面我们自然要做的就是通过计时器来爬抓链接列表里的地址。
下一步就是要通过地址列表里的地址逐一爬抓,去掉已经爬抓过的练级,并记录新的有效链接到地址列表里。
再看一下我们的main函数:
func main() { if checkFile("./data/", "url.txt").Size() == 0 { fistStart() main() } else { Timer() } }
上面的 firstStart 函数(首次执行爬抓)已经执行过了,那就会重新调用 main 函数,也就是在执行一次判断,但是因为我们的 url.txt 里已经有 12 条 Url 地址,所以这次会执行 Timer 函数。
Timer 函数里我们写了一个计时器,防止程序崩溃或者网络崩溃,所以我这里设置了 1 秒执行一次,其实没有必要这样,一秒钟执行 3-8 次也是没什么大问题的(本地情况下),如果放在服务器上,那你得看一下自己的服务器配置和带宽配置酌情考虑了。
看一下 Timer 函数吧:
func Timer() { t := time.NewTimer(time.Second * 1) <-t.C fmt.Print("\n\n\n执行爬抓\n\n") f, _ := os.OpenFile("./data/url.txt", os.O_CREATE|os.O_APPEND|os.O_RDWR, 0666) file, _ := ioutil.ReadAll(f) pageCont, _ := pageVisit(strings.Split(string(file), "\n")[0]) if checkRegexp(checkRegexp(pageCont, regTitle, 0).(string), regCheckTitle, 0).(string) != "" { fmt.Print(checkRegexp(checkRegexp(pageCont, regTitle, 0).(string), regCheckTitle, 0).(string)) fmt.Print("\n有效内容 => " + checkRegexp(pageCont, regTitle, 0).(string)) } fmt.Print("\n\n待爬抓网址共" + strconv.Itoa(len(strings.Split(string(file), "\n"))-1) + "个 => " + strings.Split(string(file), "\n")[0] + "\n") DelFirstText("./data/url.txt") Timer() }
emm...毫不夸张的表示我看自己的代码都有点吃力。
上面的代码创建了一个计时器,时间为一秒。刚开始肯定是先要打开 url.txt 文件,因为是要做删除和添加操作的,所以打开的模式是读写追加。
[plain] view plain copypageCont, _ := pageVisit(strings.Split(string(file), "\n")[0])
这一句就是获取 url.txt 里的第一条链接地址,我们要先判断一下这个链接内容是不是我们想要的,所以我又用到了之前封装的一个正则检查的函数。
checkRegexp 函数:
func checkRegexp(cont string, reg string, style int) (result interface{}) { check := regexp.MustCompile(reg) switch style { case 0: result = check.FindString(cont) case 1: result = check.FindAllString(cont, -1) default: result = check.FindAll([]byte(cont), -1) } return }
所用到的正则 => regTitle、regCheckTitle
var ( // regHref = `((ht|f)tps?)://[w]{0,3}.baidu.com/link\?[a-zA-z=0-9-\s]*` regTitle = `<title[\sa-zA-z="-]*>([^x00-xff]|[\sa-zA-Z=-:|,?"])*</title>` regCheckTitle = `(为什么|怎么)*.*([G|g][O|o][L|l][A|a][N|n][G|g]).*(怎么|实现|如何|为什么).*` )
regTitle 是为了在代码中匹配真标题,因为有些网站为了防止爬虫,做了一些假标题以混淆视听,但是这些小伎俩还是很容易解决的,这个 regTitle 足以屏蔽掉 70% 的假标题。
反正爬虫就是要和各大网站斗智斗勇。
regCheckTitle 是为了过滤出这个网址是不是我想要的内容,所以我简单的写了一串正则。这串正则的意思主要是标题要带有为什么、怎么等关键词,然后标题必须有 Golang 或者 Go 的存在,这样的内容基本上是我想要的了。
判断的代码段:
if checkRegexp(checkRegexp(pageCont, regTitle, 0).(string), regCheckTitle, 0).(string) != "" { fmt.Print(checkRegexp(checkRegexp(pageCont, regTitle, 0).(string), regCheckTitle, 0).(string)) fmt.Print("\n有效内容 => " + checkRegexp(pageCont, regTitle, 0).(string)) }
如果匹配不到,那就跳过这一条链接咯,反正不是我想要的~
DelFirstText("./data/url.txt") [plain] view plain copy func DelFirstText(file string) { var text = "" f, _ := os.OpenFile(file, os.O_RDWR|os.O_CREATE, 0666) files, _ := ioutil.ReadAll(f) var ss = strings.Split(string(files), "\n") for i := 1; i < len(ss)-1; i++ { text += ss[i] + "\n" } defer f.Close() ioutil.WriteFile(file, []byte(text), 0666) fmt.Print("\n\n删除该地址 => " + ss[0]) }
这一段就是说删掉这一条链接地址,如果没有有一段,你的爬虫将不厌其烦的去爬抓第一条链接地址,能一直爬到你的 IP 被服务器安全程序处理掉。
应该有人发现,然后呢?怎么没有把东西入库,怎么没有抓取新的链接。
emm...最近有点忙,这一段还没写,不过这些内容已经把爬虫的基本原理都给讲掉了,其实很简单对不对,就是发起 http 请求,然后通过正则匹配出自己想要的内容,再做后续的入库或者注入新鲜链接地址,让程序一直运行下去就好了。
运行一下:
嗯,就这样,有效内容就过滤出来了。
然后如果想要把文章内容提取出来,只需要一个很简单的正则就可以了,这里的处理步骤其实可以写一个单独的函数来调用。但博主现在还没有写,可能会在第三篇写上,如果访问量破2k的话大笑
为了防止有些地方细节代码没有贴上,我把 main.go 的代码贴一下吧,也可以进文章底部的链接下载整个程序的代码实例。
别跑,文章精髓内容在底部的总结,可以往下翻翻看一下。
main.go:
package main import ( "fmt" "io" "io/ioutil" "net/http" "os" "regexp" "strconv" "strings" "time" ) var ( // regHref = `((ht|f)tps?)://[w]{0,3}.baidu.com/link\?[a-zA-z=0-9-\s]*` regTitle = `<title[\sa-zA-z="-]*>([^x00-xff]|[\sa-zA-Z=-:|,?"])*</title>` regCheckTitle = `(为什么|怎么)*.*([G|g][O|o][L|l][A|a][N|n][G|g]).*(怎么|实现|如何|为什么).*` ) func main() { if checkFile("./data/", "url.txt").Size() == 0 { fistStart() main() } else { Timer() } } func Timer() { t := time.NewTimer(time.Second * 1) <-t.C fmt.Print("\n\n\n执行爬抓\n\n") f, _ := os.OpenFile("./data/url.txt", os.O_CREATE|os.O_APPEND|os.O_RDWR, 0666) file, _ := ioutil.ReadAll(f) pageCont, _ := pageVisit(strings.Split(string(file), "\n")[0]) if checkRegexp(checkRegexp(pageCont, regTitle, 0).(string), regCheckTitle, 0).(string) != "" { fmt.Print(checkRegexp(checkRegexp(pageCont, regTitle, 0).(string), regCheckTitle, 0).(string)) fmt.Print("\n有效内容 => " + checkRegexp(pageCont, regTitle, 0).(string)) } fmt.Print("\n\n待爬抓网址共" + strconv.Itoa(len(strings.Split(string(file), "\n"))-1) + "个 => " + strings.Split(string(file), "\n")[0] + "\n") DelFirstText("./data/url.txt") Timer() } func fistStart() { var num int url := "http://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&tn=39042058_20_oem_dg&wd=golang%E5%AE%9E%E7%8E%B0&oq=golang%2520%25E5%2588%25A0%25E9%2599%25A4%25E6%2595%25B0%25E7%25BB%2584&rsv_pq=d9be28ec0002df1b&rsv_t=8017GWpSLPhDmKilZQ1StC04EVpUAeLEP90NIm%2Bk5pRh5R9o57NHMO8Gaxm1TtSOo%2FvtJj%2B98%2Fsc&rqlang=cn&rsv_enter=1&inputT=3474&rsv_sug3=16&rsv_sug1=11&rsv_sug7=100&rsv_sug2=0&rsv_sug4=4230" resp, _ := http.Get(url) defer resp.Body.Close() body, _ := ioutil.ReadAll(resp.Body) reg := regexp.MustCompile(`((ht|f)tps?)://[w]{0,3}.baidu.com/link\?[a-zA-z=0-9-\s]*`) f, _ := os.OpenFile("./data/url.txt", os.O_CREATE|os.O_APPEND|os.O_RDWR, 0666) defer f.Close() for _, d := range reg.FindAllString(string(body), -1) { ff, _ := os.OpenFile("./data/url.txt", os.O_RDWR, 0666) file, _ := ioutil.ReadAll(ff) dd := strings.Split(d, "") dddd := "" for _, ddd := range dd { if ddd == "?" { ddd = `\?` } dddd += ddd } if checkRegexp(string(file), dddd, 0).(string) == "" { io.WriteString(f, d+"\n") fmt.Print("\n收集地址:" + d + "\n") num++ } // fmt.Print(string(file)) ff.Close() } fmt.Print("\n首次收集网络地址:" + strconv.Itoa(len(reg.FindAllString(string(body), -1))) + "\n") fmt.Print("\n去重后网络地址数:" + strconv.Itoa(num)) fmt.Print("\n\n首次储存成功!\n") } func pageVisit(url string) (page string, body []byte) { resp, _ := http.Get(url) defer resp.Body.Close() body, _ = ioutil.ReadAll(resp.Body) page = string(body) return } func checkFile(dir string, file string) os.FileInfo { list, _ := ioutil.ReadDir(dir) for _, info := range list { if info.Name() == file { return info } } return list[0] } func saveFile(file string, cont string) { f, _ := os.OpenFile(file, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0666) defer f.Close() io.WriteString(f, cont) } func checkRegexp(cont string, reg string, style int) (result interface{}) { check := regexp.MustCompile(reg) switch style { case 0: result = check.FindString(cont) case 1: result = check.FindAllString(cont, -1) default: result = check.FindAll([]byte(cont), -1) } return } func DelFirstText(file string) { var text = "" f, _ := os.OpenFile(file, os.O_RDWR|os.O_CREATE, 0666) files, _ := ioutil.ReadAll(f) var ss = strings.Split(string(files), "\n") for i := 1; i < len(ss)-1; i++ { text += ss[i] + "\n" } defer f.Close() ioutil.WriteFile(file, []byte(text), 0666) fmt.Print("\n\n删除该地址 => " + ss[0]) }
附代码实例:
https://download.csdn.net/download/superwebmaster/10415730
最后当然是总结了:
其实爬虫的基本原理的很简单的,步骤总的分为以下几步:
- 爬虫目标,没有一个目标的爬虫是没有灵魂的爬虫
- 自定一个源页面,也就是爬虫入口,用于获取更多资源链接
- 发送 http 请求,获取页面内容
- 过滤无效内容,防止浪费资源
- 解析页面,匹配出自己想要的内容
- 将匹配出来的有效内容入库储存
- 注入新鲜血液(新的链接)让程序不断执行下去
这是一个最基本的爬虫功能,如果想要拓展下去,其实还有很多的玩法。深入下去你也会发现更多的问题。
因为有些网站为了防爬虫,特地把数据请求留给 Ajax,所以你爬到的页面可能是完全没有内容的,这时候,你就需要和目标网站斗智斗勇,毕竟上有政策,下有对策,办法总比困难多的。
爬虫的原理,基本上已经解释清楚了,代码的逻辑是相通的,只要理解了原理,用任何编程语言实现起来其实都是可以的。
如果有任何问题都可以在 GitChat 读者圈提问,我会尽量在最快的时间里回答大家的问题。也可以加个人 QQ 私下讨论:625366394,咱们也可以玩一些更好玩的东西,如果你愿意的话。
本文首发于GitChat,未经授权不得转载,转载需与GitChat联系。
阅读全文: http://gitbook.cn/gitchat/activity/5afb9ffef084d4686fddd876
您还可以下载 CSDN 旗下精品原创内容社区 GitChat App ,阅读更多 GitChat 专享技术内容哦。
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
相关文章
- ActivityGroup中使用切换动画
ActivityGroup中使用切换动画在stack上面发现的方法,分享给大家,功能是在activitygroup切换子activity时候加载补间动画,代码如下:public void replaceContentView(String id, Intent newIntent) {View view = getLocalActivityManager().startActivity(id,newIntent.addFlag…...
2024/4/17 4:35:39 - Spark从入门到精通(一)
什么是Spark 大数据计算框架 离线批处理 大数据体系架构图(Spark) Spark包含了大数据领域常见的各种计算框架:比如Spark Core用于离线计算,Spark SQL用于交互式查询,Spark Streaming用于实时流式计算,Spark MLib用于机器学习,Spark GraphX用于图计算 Spark主要用于大数据…...
2024/5/8 11:49:15 - 高效能人士的七个习惯简介
史蒂芬柯维(Stephen R. Covey),影响人类思想的新智慧学家,美国学界的“思想巨匠”,入选“影响美国历史进程的25位人物”。2002年,福布斯将《高效能人士的七个习惯》评为有史以来最具影响力的10大管理类书籍之一。个人领域的成功:从依赖到独立习惯一:积极主动——个人愿…...
2024/4/17 4:35:57 - ionic之样式button
1、实例背景 ionic中常见的按钮button,设置按钮样式用class="button",这个是设置普通样式2、实现源码<!DOCTYPE html> <html><head><meta charset="UTF-8"><meta name="viewport" content="initial-scale…...
2024/4/17 4:35:39 - Android之最好理解的Binder机制
转载:http://weishu.me/2016/01/12/binder-index-for-newer/Binder学习指南发表于 2016-01-12 | 92条评论 | 34011次阅读毫不夸张地说,Binder是Android系统中最重要的特性之一;正如其名“粘合剂”所喻,它是系统间各个组件的桥梁,Android系统的开放式设计也很大程度…...
2024/4/17 4:36:27 - 那些浪费时间的错误-ASP.NET从入门到精通笔记第9章
在学习的过程中,总有那些让我们卡在那一小时甚至一天的问题,他打败不了我们,却总是激起我们的斗志. 零晨0:09分,终于搞定一个,庆祝,记录. 示例09\03:使用Command对象修改数据. 问题描述: GridView控件添加自定义bind()方法,如下(参见ASP.NET从入门到精通9.3.3)protected void b…...
2024/4/19 17:50:06 - Binder机制原理简述
参考自大神 https://zhuanlan.zhihu.com/p/35519585 参考自大神 https://blog.csdn.net/carson_ho/article/details/73560642 一 前言 二 Linux传统的进程间通信原理简述 2.1 Liunx 中跨进程通信主要有三个关键信息 2.2 Linux 下的传统 IPC 通信原理 三 Binder 跨进程通信原理 …...
2024/4/17 4:38:05 - 《高效能人士的 7 个习惯》知识整理
本文内容来自于个人网络学习,属于学习笔记范畴,欢迎喜欢读书的朋友一起交流。书名《高效能人士的七个习惯》内容简介 什么是高效能人士 简言之,也就是高效能人士的特点: 高产出 高产能 会平衡 高产出指的是自身在某领域/某件事上持续产出有价值的东西。高产能是指具有高产出…...
2024/5/4 14:09:38 - HTML控件用法
htmlGeneric:(只有此控件的TagName可以修改) <span id="MyControl" runat="server">Generic Control Content</span> htmlAnchor :<a href="html_anchor.aspx" id="MyControl" runat="server">My Anchor …...
2024/4/18 12:26:20 - 关于使用ActivityGroup实现活动跳转带来的问题
需要使用ActivityGroup实现Tab下内嵌多组Activity的效果。这样的教程网上很多,这里就不做详细的介绍了,大致是这样的: Window w = ActivityGroup.getLocationActivityManager().startActivity(String FLAG,Intent i); ActivityGroup.setContentView(w.getDecorView()); 这里…...
2024/4/20 17:55:18 - Spider-Python爬虫之聚焦爬虫与通用爬虫的区别
为什么要学习爬虫? 学习爬虫,可以私人订制一个搜索引擎。 大数据时代,要进行数据分析,首先要有数据源。 对于很多SEO从业者来说,从而可以更好地进行搜索引擎优化。 什么是网络爬虫? 模拟客户端发送网络请求,接收请求对应的数据,按照一定的规则,自动抓取互联网信息的程…...
2024/4/17 4:37:11 - 【爬虫教程】最详细的爬虫入门教程~
【爬虫教程】吐血整理,最详细的爬虫入门教程~初识爬虫学习爬虫之前,我们首先得了解什么是爬虫。来自于百度百科的解释:网络爬虫(又称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。通俗来…...
2024/5/4 21:51:26 - 高效能人士的七个习惯学习总结
我的初入职场的过程中,读过非常重要的两本书:《高效能人士的七个习惯》和《卓有成效的管理者》。第一本让我在生活、工作态度、习惯上,积极向上,对自己有相对全面的认识,自我发展方向明确。第二本使我远离常见的打工者心态误区,保持好的工作态度,在职场上发挥自己的潜力…...
2024/4/17 21:06:25 - 实现Material Design风格的Button
实现Material Design风格的Button #简介 The AppCompat Support Library 定义了几个很有用的style,这些Style是基于Widget.AppCompat.Button style实现的。当使用 AppCompat theme主题的时候,Widget.AppCompat.Button style 是默认使用到所有的button上面的。这些样式保证了Bu…...
2024/4/17 4:36:39 - ActivityGroup中EditText无法删除的问题
坑,以前比较少用ActivityGroup,最近使用才发现ActivityGroup中多个Activity中如果都有Edittext是无法后退删除。 网上说有种方法监听dispatchKeyEvent return就可以,我只想说~然并卵啊!!!后来发现只能重写EditText~以前没发觉,最近需要用到才发现~惭愧源码链接稍后发到下…...
2024/5/2 5:51:51 - android的事件机制之Binder机制
Binder机制Binder机制Binder机制Binder机制Binder机制Binder机制Binder机制Binder机制Binder机制Binder机制Binder机制Binder机制Binder机制Binder机制Binder机制Binder机制Binder机制Binder机制Binder机制Binder机制Binder机制Binder机制Binder机制Binder机制Binder机制Binder…...
2024/4/17 4:36:53 - FFMPEG入门
本文转自 http://blog.csdn.net/leixiaohua1020/article/details/15811977 1、分离YUV420P像素数据中的Y、U、V分量/** * Split Y, U, V planes in YUV420P file. * @param url Location of Input YUV file. * @param w Width of Input YUV file. * @param h Height of …...
2024/5/4 19:25:41 - 简易Java爬虫制作
一、文章来由本来最近任务挺多,但是今天想放松一下,正巧Bill喜欢玩英语配音,而配音都是在配音软件的云上,我想把那些都拿到,于是就写一了一个爬虫,接着就有了这篇爬虫教程~~二、爬虫!!爬虫!!首先要搞清什么叫爬虫~~网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社…...
2024/5/5 0:09:13 - 高效能人士的七个习惯 - 读书笔记(XMind)
书籍推荐:《高效能人士的七个习惯》 ★★★★★ 此书放在案头已有多年,最开始是某位神秘人士(也就是我忘记是谁啦)推荐给我的,偶尔挑选几章来读,不成体系,最新学习时间管理,要事第一,又把此书读了一遍,发现其对工作,生活,事业等都具有极强的指导意义,并能从中学习…...
2024/5/4 23:52:17 - html5如何创建按钮button
HTML 5 <button> 标签定义和用法 <button> 标签定义按钮。您可以在 button 元素中放置内容,比如文档或图像。这是该元素与由 input 元素创建的按钮的不同之处。HTML 4.01 与 HTML 5 之间的差异 在 HTML 5 中有一个新属性:autofocus。例子: <button>TestBt…...
2024/4/18 9:46:31
最新文章
- SpringBoot+Redission实现排行榜功能
SpringBootRedission实现排行榜功能 demo地址:ranking-demo: 排行榜DEMO (gitee.com) 一、业务需求 实现一个排行榜,要求按照分数和达成这个分数的时间排序,即相同分数下,时间早的在上面 二、Redis中的zSet(有序集合) 1.简介 …...
2024/5/8 13:28:56 - 梯度消失和梯度爆炸的一些处理方法
在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言,在此感激不尽。 权重和梯度的更新公式如下: w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...
2024/5/7 10:36:02 - C# Solidworks二次开发:六种配合方式以及注意事项API详解
今天要写的文章是关于配合的一些API介绍。 如果大家还不知道创建配合的API用的是哪个,可以看一下我之前写的文章:C# Solidworks二次开发:创建距离配合以及移动组件API详解_solidworks transform2-CSDN博客 (1)今天要…...
2024/5/8 9:57:38 - [C++/Linux] UDP编程
一. UDP函数 UDP(用户数据报协议,User Datagram Protocol)是一种无连接的网络协议,用于在互联网上交换数据。它允许应用程序发送数据报给另一端的应用程序,但不保证数据报能成功到达,也就是说,它…...
2024/5/3 8:59:07 - Java深度优先搜索DFS(含面试大厂题和源码)
深度优先搜索(Depth-First Search,简称DFS)是一种用于遍历或搜索树或图的算法。DFS 通过沿着树的深度来遍历节点,尽可能深地搜索树的分支。当节点v的所在边都已被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这个…...
2024/5/5 8:52:24 - 【外汇早评】美通胀数据走低,美元调整
原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...
2024/5/8 6:01:22 - 【原油贵金属周评】原油多头拥挤,价格调整
原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...
2024/5/7 9:45:25 - 【外汇周评】靓丽非农不及疲软通胀影响
原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...
2024/5/4 23:54:56 - 【原油贵金属早评】库存继续增加,油价收跌
原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...
2024/5/7 14:25:14 - 【外汇早评】日本央行会议纪要不改日元强势
原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...
2024/5/4 23:54:56 - 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响
原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...
2024/5/4 23:55:05 - 【外汇早评】美欲与伊朗重谈协议
原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...
2024/5/4 23:54:56 - 【原油贵金属早评】波动率飙升,市场情绪动荡
原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...
2024/5/7 11:36:39 - 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试
原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...
2024/5/4 23:54:56 - 【原油贵金属早评】市场情绪继续恶化,黄金上破
原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...
2024/5/6 1:40:42 - 【外汇早评】美伊僵持,风险情绪继续升温
原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...
2024/5/4 23:54:56 - 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势
原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...
2024/5/4 23:55:17 - 氧生福地 玩美北湖(上)——为时光守候两千年
原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...
2024/5/7 9:26:26 - 氧生福地 玩美北湖(中)——永春梯田里的美与鲜
原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...
2024/5/4 23:54:56 - 氧生福地 玩美北湖(下)——奔跑吧骚年!
原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...
2024/5/4 23:55:06 - 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!
原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...
2024/5/5 8:13:33 - 「发现」铁皮石斛仙草之神奇功效用于医用面膜
原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...
2024/5/4 23:55:16 - 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者
原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...
2024/5/4 23:54:58 - 广州械字号面膜生产厂家OEM/ODM4项须知!
原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...
2024/5/6 21:42:42 - 械字号医用眼膜缓解用眼过度到底有无作用?
原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...
2024/5/4 23:54:56 - 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...
解析如下:1、长按电脑电源键直至关机,然后再按一次电源健重启电脑,按F8健进入安全模式2、安全模式下进入Windows系统桌面后,按住“winR”打开运行窗口,输入“services.msc”打开服务设置3、在服务界面,选中…...
2022/11/19 21:17:18 - 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。
%读入6幅图像(每一幅图像的大小是564*564) f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...
2022/11/19 21:17:16 - 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...
win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面,在等待界面中我们需要等待操作结束才能关机,虽然这比较麻烦,但是对系统进行配置和升级…...
2022/11/19 21:17:15 - 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...
有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows,请勿关闭计算机”的提示,要过很久才能进入系统,有的用户甚至几个小时也无法进入,下面就教大家这个问题的解决方法。第一种方法:我们首先在左下角的“开始…...
2022/11/19 21:17:14 - win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...
置信有很多用户都跟小编一样遇到过这样的问题,电脑时发现开机屏幕显现“正在配置Windows Update,请勿关机”(如下图所示),而且还需求等大约5分钟才干进入系统。这是怎样回事呢?一切都是正常操作的,为什么开时机呈现“正…...
2022/11/19 21:17:13 - 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...
Win7系统开机启动时总是出现“配置Windows请勿关机”的提示,没过几秒后电脑自动重启,每次开机都这样无法进入系统,此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一:开机按下F8,在出现的Windows高级启动选…...
2022/11/19 21:17:12 - 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...
有不少windows10系统用户反映说碰到这样一个情况,就是电脑提示正在准备windows请勿关闭计算机,碰到这样的问题该怎么解决呢,现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法:1、2、依次…...
2022/11/19 21:17:11 - 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...
今天和大家分享一下win7系统重装了Win7旗舰版系统后,每次关机的时候桌面上都会显示一个“配置Windows Update的界面,提示请勿关闭计算机”,每次停留好几分钟才能正常关机,导致什么情况引起的呢?出现配置Windows Update…...
2022/11/19 21:17:10 - 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...
只能是等着,别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚,只能是考虑备份数据后重装系统了。解决来方案一:管理员运行cmd:net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...
2022/11/19 21:17:09 - 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?
原标题:电脑提示“配置Windows Update请勿关闭计算机”怎么办?win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢?一般的方…...
2022/11/19 21:17:08 - 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...
关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!关机提示 windows7 正在配…...
2022/11/19 21:17:05 - 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...
钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...
2022/11/19 21:17:05 - 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...
前几天班里有位学生电脑(windows 7系统)出问题了,具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面,长时间没反应,无法进入系统。这个问题原来帮其他同学也解决过,网上搜了不少资料&#x…...
2022/11/19 21:17:04 - 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...
本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法,并在最后教给你1种保护系统安全的好方法,一起来看看!电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中,添加了1个新功能在“磁…...
2022/11/19 21:17:03 - 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...
许多用户在长期不使用电脑的时候,开启电脑发现电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机。。.这要怎么办呢?下面小编就带着大家一起看看吧!如果能够正常进入系统,建议您暂时移…...
2022/11/19 21:17:02 - 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...
配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!配置windows update失败 还原更改 请勿关闭计算机&#x…...
2022/11/19 21:17:01 - 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...
不知道大家有没有遇到过这样的一个问题,就是我们的win7系统在关机的时候,总是喜欢显示“准备配置windows,请勿关机”这样的一个页面,没有什么大碍,但是如果一直等着的话就要两个小时甚至更久都关不了机,非常…...
2022/11/19 21:17:00 - 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...
当电脑出现正在准备配置windows请勿关闭计算机时,一般是您正对windows进行升级,但是这个要是长时间没有反应,我们不能再傻等下去了。可能是电脑出了别的问题了,来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...
2022/11/19 21:16:59 - 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...
我们使用电脑的过程中有时会遇到这种情况,当我们打开电脑之后,发现一直停留在一个界面:“配置Windows Update失败,还原更改请勿关闭计算机”,等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢࿰…...
2022/11/19 21:16:58 - 如何在iPhone上关闭“请勿打扰”
Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...
2022/11/19 21:16:57