8. 函数
1.1 概述学习了一些基础语法,开始学习写函数了,分享几个自己写的函数。
MD5
获取当前时间戳
获取当前时间字符串
生成签名
1.2 函数定义12345func function_name(input1 type1, input2 type2) (type1, type2) { // 函数体 // 返回多个值 return value1, value2}
函数用 func 声明。
函数可以有一个或多个参数,需要有参数类型,用 , 分割。
函数可以有一个或多个返回值,需要有返回值类型,用 , 分割。
函数的参数是可选的,返回值也是可选的。
1.3 值传递传递参数时,将参数复制一份传递到函数中,对参数进行调整后,不影响参数值。
Go 语言默认是值传递。
1.4 引用传递传递参数时,将参数的地址传递到函数中,对参数进行调整后,影响参数值。
这个是 [Go - Struct 结构体]的例子:
1234567891011121314151617181920212223242526272829303132333435//demo_13.gopackage ...
9. chan通道
1.1 概述原来分享基础语法的时候,还未分享过 chan 通道,这次把它补上。
chan 可以理解为队列,遵循先进先出的规则。
在说 chan 之前,咱们先说一下 go 关键字。
在 go 关键字后面加一个函数,就可以创建一个线程,函数可以为已经写好的函数,也可以是匿名函数。
举个例子:
123456789func main() { fmt.Println("main start") go func() { fmt.Println("goroutine") }() fmt.Println("main end")}
输出:
12main startmain end
为什么没有输出 goroutine ?
首先,我们清楚 Go 语言的线程是并发机制,不是并行机制。
那么,什么是并发,什么是并行?
并发是不同的代码块交替执行,也就是交替可以做不同的事情。
并行是不同的代码块同时执行,也就是同时可以做不同的事情。
举个生活化场景的例子:
你正在家看书,忽然电话来了,然后你接电话,通话完成后 ...
6. map集合
1.2 概述Map 集合是无序的 key-value 数据结构。
Map 集合中的 key / value 可以是任意类型,但所有的 key 必须属于同一数据类型,所有的 value 必须属于同一数据类型,key 和 value 的数据类型可以不相同。
1.2 声明 Map12345678910111213141516171819202122232425262728293031323334//demo_14.gopackage mainimport ( "fmt")func main() { var p1 map[int]string p1 = make(map[int]string) p1[1] = "Tom" fmt.Println("p1 :", p1) var p2 map[int]string = map[int]string{} p2[1] = "Tom" fmt.Println("p2 :", p2) var p3 map[int]s ...
10. defer函数
1.1概述defer 函数大家肯定都用过,它在声明时不会立刻去执行,而是在函数 return 后去执行的。
它的主要应用场景有异常处理、记录日志、清理数据、释放资源 等等。
这篇文章不是分享 defer 的应用场景,而是分享使用 defer 需要注意的点。
咱们先从一道题开始,一起来感受下 …
1234567891011121314func calc(index string, a, b int) int { ret := a + b fmt.Println(index, a, b, ret) return ret}func main() { x := 1 y := 2 defer calc("A", x, calc("B", x, y)) x = 3 defer calc("C", x, calc("D", x, y)) y = 4}
输出什么?
…
接下来,先容我分享几个小例子,再进行作答。
执行顺序12345678func main() { def ...
4. slice切片
1.1概述切片是一种动态数组,比数组操作灵活,长度不是固定的,可以进行追加和删除。
len() 和 cap() 返回结果可相同和不同。
1.2声明切片1234567891011121314151617181920212223242526//demo_7.gopackage mainimport ( "fmt")func main() { var sli_1 [] int //nil 切片 fmt.Printf("len=%d cap=%d slice=%v\n",len(sli_1),cap(sli_1),sli_1) var sli_2 = [] int {} //空切片 fmt.Printf("len=%d cap=%d slice=%v\n",len(sli_1),cap(sli_2),sli_2) var sli_3 = [] int {1, 2, 3, 4, 5} fmt.Printf("len=%d cap=%d slice=%v\n" ...
9.随机请求头
123456789101112131415from fake_useragent import UserAgent # 下载:pip install fake-useragentimport requestsua = UserAgent() # 实例化,需要联网但是网站不太稳定-可能耗时会长一些print(ua.random) # 随机产生headers = { 'User-Agent': ua.random # 伪装 }print(headers)# 请求if __name__ == '__main__': url = 'https://www.baidu.com/' response = requests.get(url, headers=headers ,proxies={"http":"117.136.27.43"}) print(response.status_code)
1234 ...
1.Scrapy 基本介绍与使用
1.Scrapy 基本介绍与使用一, 爬虫工程化 在之前的学习中我们已经掌握了爬虫这门技术需要的大多数的技术点, 但是我们现在写的代码还很流程化, 很难进行商用的. 想要我们的爬虫达到商用级别, 必须要对我们现在编写的爬虫代码进行大刀阔斧式的重组, 已达到工程化的爬虫. 何为工程化, 就是让你的程序更加的有体系, 有逻辑, 更加的模块化.
就好比, 我们家里以前做过鞋子, 我妈妈给我做鞋, 她需要从画图纸到裁剪到最后的缝合, 一步一步的完成一双鞋子的制作. 这种手工鞋子如果每年做个几双, 没问题. 我妈妈辛苦一点, 也能搞定. 但是, 如果现在我想去售卖这个鞋子. 再依靠妈妈一双一双的缝制. 你不赔死, 也得让你妈打死. 为什么? 第一, 产能跟不上. 一个人的力量是有限的, 第二, 一个人要完整的把制作鞋子的工艺从头搞到尾. 就算你想招人分担一下. 貌似也不好找这样厉害的手艺人. 怎么办? 聪明的你可能已经想到了. 从头到尾完成一双鞋的人不好找. 那我就把这个工艺过程分开. 分成4份, 画图, 裁剪, 缝合, 验收. 招4个人. 每个人就负责一小部分. 并且这一小部分是 ...
4.Scrapy抓取全网站数据
4.Scrapy抓取全网站数据一. 使用常规Spider我们把目光对准汽车之家. 抓取二手车信息.
注意, 汽车之家的访问频率要控制一下. 要不然会跳验证的.
1DOWNLOAD_DELAY = 3
12345678910111213141516171819202122232425class ErshouSpider(scrapy.Spider): name = 'ershou' allowed_domains = ['che168.com'] start_urls = ['https://www.che168.com/beijing/a0_0msdgscncgpi1ltocsp100exx0/?pvareaid=102179#currengpostion'] def parse(self, resp, **kwargs): # print(resp.text) # 链接提取器 le = LinkExtractor(restrict_xpaths=(&quo ...
2.Scrapy管道
2.Scrapy管道在上一小节中, 我们初步掌握了Scrapy的基本运行流程以及基本开发流程. 本节继续讨论关于Scrapy更多的内容.
一. 关于管道上一节内容, 我们已经可以从spider中提取到数据. 然后通过引擎将数据传递给pipeline, 那么在pipeline中如何对数据进行保存呢? 我们主要针对四种数据存储展开讲解.
前三个案例以http://datachart.500.com/ssq/为案例基础. 最后一个以https://www.tupianzj.com/bizhi/DNmeinv/为案例基础.
1. csv文件写入 写入文件是一个非常简单的事情. 直接在pipeline中开启文件即可. 但这里要说明的是. 如果我们只在process_item中进行处理文件是不够优雅的. 总不能有一条数据就open一次吧
1234567class CaipiaoFilePipeline: def process_item(self, item, spider): with open("caipiao.txt", mode= ...
3.模拟登录与中间件
3.模拟登录与中间件一. Scrapy处理cookie 在requests中我们讲解处理cookie主要有两个方案. 第一个方案. 从浏览器里直接把cookie搞出来. 贴到heades里. 这种方案, 简单粗暴. 第二个方案是走正常的登录流程. 通过session来记录请求过程中的cookie. 那么到了scrapy中如何处理cookie? 其实也是这两个方案.
首先, 我们依然是把目标定好, 还是我们的老朋友, https://user.17k.com/ck/author/shelf?page=1&appKey=2406394919
这个url必须要登录后才能访问(用户书架). ==对于该网页而言==, 就必须要用到cookie了. 首先, 创建项目, 建立爬虫. 把该填的地方填上.
123456789101112import scrapyfrom scrapy import Request, FormRequestclass LoginSpider(scrapy.Spider): name = ...
1.什么是爬虫?
1.什么是爬虫?不知道各位是否遇到过这样的需求, 就是我们总是希望能够保存互联网上的一些重要的数据信息为己所用。比如:
在浏览到一些优秀的图片时,总想保存起来留为日后做桌面上的壁纸
在浏览到一些重要的数据时(各行各业),希望保留下来日后为自己进行各种销售行为增光添彩
在浏览到一些好看的视频时, 希望保存在硬盘里供日后使用
在浏览到一些十分优秀的歌声曲目时, 希望保存下来供我们在烦闷的生活中增添一份精彩
那么恭喜你,本教程将十分的适合于你。因为爬虫就是通过编写程序来爬取互联网上的优秀资源(图片, 音频, 视频, 数据)
2.爬虫和Python爬虫一定要用Python么? 非也~ 用Java也行, C也可以. 请各位记住,编程语言只是工具. 抓到数据是你的目的. 用什么工具去达到你的目的都是可以的. 和吃饭一样, 可以用叉子也可以用筷子, 最终的结果都是你能吃到饭. 那为什么大多数人喜欢用Python呢? 答案: 因为Python写爬虫简单. 不理解? 问: 为什么吃米饭不用刀叉? 用筷子? 因为简单! 好用!
而Python是众多编程语言中, 小白上手最快, 语法最简单。更重要的是, ...
7.selenium的介绍
selenium的介绍本节主要学习selenium自动化测试框架在爬虫中的应用,selenium能够大幅降低爬虫的编写难度,但是也同样会大幅降低爬虫的爬取速度。在逼不得已的情况下我们可以使用selenium进行爬虫的编写。
知识点:
了解 selenium的工作原理
了解 selenium以及chromedriver的安装
掌握 标签对象click点击以及send_keys输入
1. selenium运行效果展示
Selenium是一个Web的自动化测试工具,最初是为网站自动化测试而开发的,Selenium 可以直接调用浏览器,它支持所有主流的浏览器(包括PhantomJS这些无界面的浏览器),可以接收指令,让浏览器自动加载页面,获取需要的数据,甚至页面截屏等。我们可以使用selenium很容易完成之前编写的爬虫,接下来我们就来看一下selenium的运行效果
1.1 chrome浏览器的运行效果
在下载好chromedriver以及安装好selenium模块后,执行下列代码并观察运行的过程
123456789101112131415161718from selenium im ...
6.cookies
cookies我们在之前的爬⾍中其实已经使⽤过headers了。header为HTTP协议中的请求头。⼀般存放⼀些和请求内容⽆关的数据。有时也会存放⼀些安全验证信息。⽐如常⻅的User-Agent, token, cookie等。通过requests发送的请求, 我们可以把请求头信息放在headers中。也可以单独进⾏存放, 最终由requests⾃动帮我们拼接成完整的http请求头。
有些网站需要登录才能看到信息,比如我想用17k小说的书架信息,必须要登录才能看到这个信息。
所以我们需要首先登陆,然后在登陆的时候要获取到登陆所需要的信息,如下图所示:
点击登录的时候抓包就能抓到我们用到的账号和密码:
然后我们就可以开始写了,注意,这里请求的url是这在这里的。
然后在书架页,这些书籍信息隐藏在json中,需要找到json信息 ,然后解析。
12345678910111213141516171819202122import requestssession = requests.session()data = {'loginName': ' ...
5.bs4解析库
bs4解析库今天来继续介绍一个爬虫的解析库,和前面说过的xpath,和正则表达式的是同样的原理,就是把所需要的信息从网页中解析出来。
我们先拿一小段代码来做一下学习,这是一段html代码,接下来需要从中找出我们所需要的文本和链接等相关信息。
12345678910111213141516171819202122232425262728293031323334<html lang="en"><head> <meta charset="UTF-8" /> <title>测试bs4</title></head><body> <div> <p>百里守约</p> </div> <div class="song"> <p>李清照</p> <p>王安石</p> <p>苏轼</p> <p>柳宗元</p& ...
4.正则表达式
正则表达式Regular Expression, 正则表达式, ⼀种使⽤表达式的⽅式对字符串进⾏匹配的语法规则。
我们抓取到的⽹⻚源代码本质上就是⼀个超⻓的字符串, 想从⾥⾯提取内容。⽤正则再合适不过了。
正则的优点:速度快, 效率⾼, 准确性⾼ 正则的缺点:新⼿上⼿难度有点⼉⾼。
不过只要掌握了正则编写的逻辑关系, 写出⼀个提取⻚⾯内容的正则其实并不复杂
正则的语法:使⽤元字符进⾏排列组合⽤来匹配字符串 在线测试正则表达式 https://tool.oschina.net/regex/
元字符:具有固定含义的特殊符号 常⽤元字符:
. 匹配除换⾏符以外的任意字符
\w 匹配字⺟或数字或下划线
\s 匹配任意的空⽩符 \d 匹配数字
\n 匹配⼀个换⾏符
\t 匹配⼀个制表符
^ 匹配字符串的开始 $ 匹配字符串的结尾
\W 匹配⾮字⺟或数字或下划线
\D 匹配⾮数字
\S 匹配⾮空⽩符
a|b 匹配字符a或字符b
() 匹配括号内的表达式,也表示⼀个组
[…] 匹配字符组中的字符
[^…] 匹配除了字符组中字符的所有字符
量词: 控制前⾯的元字符出现的次数
* 重复零次或更多次 ...
2.requst请求库
requst请求库常⽤的抓取⻚⾯的模块通常使⽤⼀个第三⽅模块requests, 这个模块的优势就是⽐urllib还要简单,并且处理各种请求都⽐较⽅便。
既然是第三⽅模块,那就需要我们对该模块进⾏安装,安装⽅法:
1pip install requests
如果安装速度慢的话可以改⽤国内的源进⾏下载安装.
1pip install -i https://pypi.tuna.tsinghua.edu.cn/simple requests
OK. 接下来我们来看看requests能带给我们什么?我们先请求一下百度首页,一般的案例都是从这里开始的,俗称梦开始的地方:
案例1:请求百度首页源代码12345import requestsurl = "https://www.baidu.com/"response = requests.get(url)response.encoding = "utf-8"print(response.text)
这样运行的话就把百度首页的html提取出来了。
案例2:搜狗搜索词,交互式返回结果123456789101 ...
3.xpath解析库
xpath解析库在上⼀章中, 我们基本上掌握了抓取整个⽹⻚的基本技能。但是呢, ⼤多数情况下, 我们并不需要整个⽹⻚的内容, 只是需要那么⼀⼩部分。怎么办呢? 这就涉及到了数据提取的问题。
本课程中, 提供三种解析⽅式:
xpath解析
bs4解析
re解析
这三种⽅式可以混合进⾏使⽤, 完全以结果做导向, 只要能拿到你想要的数据。⽤什么⽅案并不重要。当你掌握了这些之后。再考虑性能的问题。
XPath是⼀⻔在 XML ⽂档中查找信息的语⾔, XPath可⽤来在 XML⽂档中对元素和属性进⾏遍历,⽽我们熟知的HTML恰巧属于XML的⼀个⼦集,所以完全可以⽤xpath去查找html中的内容。
⾸先, 先了解⼏个概念:
在上述html中,
book, id, name, price….都被称为节点.
Id, name, price, author被称为book的⼦节点
book被称为id, name, price, author的⽗节点
id, name, price,author被称为同胞节点
OK~ 有了这些基础知识后, 我们就可以开始了解xpath的基本语法了
在py ...