赞
踩
前提:本篇文章的前提是你要会python基本语法,并且已经安装好了pycharm,我使用的是python3.8版本
声明:本篇博客纯属教学,都是合法数据,涉及的网站例子如介意,请联系删除
1:爬虫基础入门
1-1:爬虫简介
网络爬虫(又称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。另外一些不常使用的名字还有蚂蚁、自动索引、模拟程序或者蠕虫。
所谓爬虫,就是通过编写程序,模拟浏览器上网,然后让其去互联网上抓取数据的过程
抓取互联网上的数据,为我所用,有了大量的数据,就如同有了一个数据银行一样,可以使用这些数据做一些产品,不如最漂亮的美女图片网,技术文章网,搞笑故事APP等等
爬虫可分为3类
- 通用爬虫:抓取系统重要组成部分,抓取的是一整张页面数据
- 聚焦爬虫:是建立在通用爬虫的基础上,抓取的是页面中特定的局部内容
- 增量式爬虫:检测网站中数据更新的更新,只会抓取网站中最新 更新出来的数据
1-2:爬虫是违法的吗
在探究爬虫额合法性之前,我们先介绍一个君子协议:robots.txt协议,这个协议几乎每个网站都有。
robots.txt文件是一个文本文件,使用任何一个常见的文本编辑器,比如Windows系统自带的Notepad,就可以创建和编辑它。robots.txt是一个协议,而不是一个命令。robots.txt是搜索引擎中访问网站的时候要查看的第一个文件。robots.txt文件告诉蜘蛛程序在服务器上什么文件是可以被查看的。
当一个搜索蜘蛛访问一个站点时,它会首先检查该站点根目录下是否存在robots.txt,如果存在,搜索机器人就会按照该文件中的内容来确定访问的范围;如果该文件不存在,所有的搜索蜘蛛将能够访问网站上所有没有被口令保护的页面。百度官方建议,仅当您的网站包含不希望被搜索引擎收录的内容时,才需要使用robots.txt文件。如果您希望搜索引擎收录网站上所有内容,请勿建立robots.txt文件。
如果将网站视为酒店里的一个房间,robots.txt就是主人在房间门口悬挂的“请勿打扰”或“欢迎打扫”的提示牌。这个文件告诉来访的搜索引擎哪些房间可以进入和参观,哪些房间因为存放贵重物品,或可能涉及住户及访客的隐私而不对搜索引擎开放。但robots.txt不是命令,也不是防火墙,如同守门人无法阻止窃贼等恶意闯入者。
首先要认识User-agent、Disallow、Allow是什么意思:
- User-agent表示定义哪个搜索引擎,如User-agent:Baiduspider,定义百度蜘蛛;
- Disallow表示禁止访问;
- Allow表示运行访问;
一个网站的robots.txt打开方式是其官网域名地址加上robots.txt
比如CSDN
又如百度
为什么说是君子协议
因为robots.txt只是一个文本,只是明确指出网站上那些 东西可爬,那些不可爬,但是不可爬的那些也无法阻止你真正的去爬取里面的数据,所以说是君子协议,防君子不防小人
所以就有了反爬机制和反反爬机制
反爬机制:
- 为了防止爬虫爬取到关键的隐私数据,各个网站制定的策略
反反爬机制
- 为了破解各个网站的反爬机制而制定的各种策略
了解了君子协议之后,我们明白了,爬虫在法律中是不被禁止的
- 君子协议允许爬取的数据,我们爬取之后不违法
- 我们不能恶意攻击,干扰了被访问网站的正常运营
- 君子协议不允许爬取的数据,涉及到商业机密或者是受法律保护的特性类型的数据或信息,爬取之后是违法的,要负相应的法律责任
1-3:http和https协议
http协议
http是一个简单的请求-响应协议,它通常运行在TCP之上。它指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应。请求和响应消息的头以ASCII码形式给出;而消息内容则具有一个类似MIME的格式。这个简单模型是早期Web成功的有功之臣,因为它使开发和部署非常地直截了当。
https
HTTPS (全称:Hyper Text Transfer Protocol over SecureSocket Layer),是以安全为目标的 HTTP 通道,在HTTP的基础上通过传输加密和身份认证保证了传输过程的安全性 。HTTPS 在HTTP 的基础下加入SSL 层,HTTPS 的安全基础是 SSL,因此加密的详细内容就需要 SSL。 HTTPS 存在不同于 HTTP 的默认端口及一个加密/身份验证层(在 HTTP与 TCP 之间)。这个系统提供了身份验证与加密通讯方法。它被广泛用于万维网上安全敏感的通讯,例如交易支付等方面。
https协议的加密方式(想深入的了解可以自行查找资料)
- 对称密钥加密
- 非对称密钥加密
- 证书密钥加密
无论是http协议还是https协议,都是请求与响应
常用的请求头信息:
- User-Agent:请求载体的身份标识
- Connection:请求完毕后,是否断开连接还是保持连接
常用的响应头信息:
- Content-Type:服务器响应回客户端的数据类型,如:text/plain;application/json等等
比如我们使用谷歌浏览器访问百度首页
再如我们使用火狐浏览器访问CSDN的周排行
1-4:第一个爬虫程序-requests模块
从上面的简介中,我们已经知道爬虫本质就是使用程序编码替代浏览器访问网络资源获取响应的数据信息
python为我们提供了2个模块来抓取网络数据,urllib模块和requests模块,相比之下,requests模块的使用简单的要多,所以我们采用requests模块来演示
要使用requests模块,首先得安装这个模块
- pip install requests
使用requests模块的简单编码流程
- 自动url
- 发起请求
- 获取响应数据
- 持久化存储
下面我们使用requests模块来访问百度首页
# -*- coding: utf-8 -*- # 导入requests模块 import requests if __name__ == "__main__": # 指定url get_url="https://www.baidu.com" # 发起请求,返回一个响应对象 response = requests.get(url=get_url) # 设置响应编码,免得中文乱码 response.encoding = 'utf-8' # 获取响应数据, page_text = response.text # 把数据保存在my_bai_du.html中 with open('./my_bai_du.html', 'w', encoding='utf-8') as fp: fp.write(page_text)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
1-5:乱码问题
response.text和response.content的 区别
- response.text返回的类型是str
- response.content返回的类型是bytes,可以通过decode()方法将bytes类型转为str类型
- 推荐使用:response.content.decode()的方式获取相应的html页面
扩展理解
response.text
- 解码类型:根据HTTP头部对响应的编码做出有根据的推测,推测的文本编码
- 如何修改编码方式:response.encoding = ‘gbk’
response.content
- 解码类型:没有指定
- 如何修改编码方式:response.content.decode(‘utf8’)
如我们上面的例子可以改为
# -*- coding: utf-8 -*- # 导入requests模块 import requests if __name__ == "__main__": # 指定url get_url="https://www.baidu.com" # 发起请求,返回一个响应对象 response = requests.get(url=get_url) # 获取响应数据, page_content = response.content.decode('utf8') # 把数据保存在my_bai_du.html中 with open('./my_bai_du2.html', 'w', encoding='utf-8') as fp: fp.write(page_content)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
结果是一样的
如果以上的问题都没有解决,那么就对我们特定的乱码数据data=data.encode(‘iso-8859-1’).decode(‘gbk’)
2:requests模块深入学习
我们可以看到requests模块的请求中,最终的方法里可以传递各种参数
2-1:图片和视频数据的爬取
我们知道,网页上的图片也是一个链接,所以我们爬取图片数据,其实也是访问图片链接下载下来
我们网上找一个美女图片
接着就开弄吧
# -*- coding: utf-8 -*- import requests if __name__ == "__main__": # 图片链接 url="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1608264646866&di=c80756b05ed2147e5162e07f1a97b785&imgtype=0&src=http%3A%2F%2Finews.gtimg.com%2Fnewsapp_match%2F0%2F10634033150%2F0.jpg" response = requests.get(url=url) # 因为图片是二进制形式的,所以使用content img_data = response.content # wb表示以二进制的形式写入 with open('../image/mei_nv.jpg','wb') as wp: wp.write(img_data)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
爬取后的图片就在/image/下的mei_nv.jpg
同样的,视频也是一样的原理,我们找一个视频,不如我找冯提莫唱的《他不爱我》视频
开搞
# -*- coding: utf-8 -*- import requests if __name__ == "__main__": # 视频链接 url="https://ugcws.video.gtimg.com/uwMROfz2r57IIaQXGdGnCmdeB3eAEbQczPtowErLZ6kvPmTO/szg_41485149_50001_faf5f8ef210447878f98212a76d0c39c.f622.mp4?sdtfrom=v1010&guid=3a4bd3278692a44ca0baaf89bc1826ec&vkey=B5759EBA404F5A4E738F42D51D518A37C3B35D0D22BC09129DDAA8FD9F3076EA86A75391BE94300827476F985EA085854C761BC46BB04C0921C60DD473D6DF289318C473BF399D088566E1CA537D2DE93804D17D39BF753A57AC841D2267FE822A2D6F538071BDC8606F85425EBBE811104A51BA85182223B767351108CD7DDC" response = requests.get(url=url) # 因为视频是二进制形式的,所以使用content img_data = response.content with open('../image/视频.mp4','wb') as wp: wp.write(img_data)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
结果的得到我们的视频
2-2:传参
模拟百度搜索
我们模拟一下百度搜索的http请求,这个就需要传参,http://www.baidu.com/s?wd=林高禄
这个就需要我们传递参数,我可以直接requests.get(’http://www.baidu.com/s?wd=林高禄‘)得到结果,但是如果参数多的时候,我们不建议这样做,我们可以用一个字典封装参数传递进去
# -*- coding: utf-8 -*- # 导入requests模块 import requests if __name__ == "__main__": # 指定url get_url="http://www.baidu.com/s" # 封装参数,上面的url中?可以不要,发起请求的时候会自动加上 params={ 'wd':'林高禄' } # 发起请求,返回一个响应对象 response = requests.get(url=get_url,params=params) # 获取响应数据, page_content = response.content.decode('utf8') print(page_content) # 把数据保存在my_bai_du.html中 with open('./my_bai_du.html', 'w', encoding='utf-8') as fp: fp.write(page_content)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
得出的结果是一样的
2-3:UA伪装
基于上面的模拟百度搜索传参,我们使用的是http协议,如果改成https协议,我么再试一下
浏览器访问是可以的
但是我们使用代码爬取的时候,是不行的
# -*- coding: utf-8 -*- # 导入requests模块 import requests if __name__ == "__main__": # 指定url get_url="https://www.baidu.com/s" # 封装参数,上面的url中?可以不要,发起请求的时候会自动加上 params={ 'wd':'林高禄' } # 发起请求,返回一个响应对象 response = requests.get(url=get_url,params=params) # 获取响应数据, page_content = response.content.decode('utf8') print(page_content) # 把数据保存在my_bai_du.html中 with open('./my_bai_du.html', 'w', encoding='utf-8') as fp: fp.write(page_content)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
运行看输出结果,得不到真实的数据
这就需要我们进行UA伪装,所谓UA伪装就是User-Agent,请求载体的身份标识,让我们的爬虫伪装成正常的请求载体的请求
明白的UA伪装后,我们就在我们的代码基础上加入请求头headers ,进行UA伪装
# -*- coding: utf-8 -*- # 导入requests模块 import requests if __name__ == "__main__": # 指定url get_url="https://www.baidu.com/s" # UA伪装 headers = { 'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) >Chrome/86.0.4240.193 Safari/537.36' } # 封装参数,上面的url中?可以不要,发起请求的时候会自动加上 params={ 'wd':'林高禄' } # 发起请求,返回一个响应对象 response = requests.get(url=get_url,params=params,headers=headers) # 获取响应数据, page_content = response.content.decode('utf8') print(page_content) # 把数据保存在my_bai_du.html中 with open('./my_bai_du.html', 'w', encoding='utf-8') as fp: fp.write(page_content)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
2-4:UA伪装头部信息模块UserAgent
上面的UA伪装头部信息User-Agent是我们从抓包工具中复制出来的,也就是每次请求都是固定的浏览器载体标识,请求次数过多还是会被服务器察觉,所以我们使用伪装模块UserAgent,来生成我们的伪装
要使用UserAgent模块,得安装fake_useragent模块,因为UserAgent是在fake_useragent下的字模块
- pip install fake_useragent
我们演示一下UserAgent模块
# -*- coding: utf-8 -*- from fake_useragent import UserAgent # 实例化 UserAgent 类 ua = UserAgent() # 对应浏览器的头部信息 print(ua.ie) print(ua.internetexplorer) print(ua.opera) print(ua.chrome) print(ua.firefox) print(ua.safari) # 随机返回头部信息,推荐使用 print('----------分隔符----------') print(ua.random)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
可见UserAgent为我们提供了很多种请求头,那么这些数据是从哪里来的,我这里只做简单的介绍,具体细节你们可以跟踪源码
debug看一下
我们找一下数据
知道是json,打开复制格式化一下
这就是数据源
了解了UserAgent模块,我们基于上面的例子,使用UserAgent模块改造
# -*- coding: utf-8 -*- # 导入requests模块 import requests # 导入UserAgent模块 from fake_useragent import UserAgent if __name__ == "__main__": # 实例化 UserAgent 类 ua = UserAgent() # 指定url get_url="https://www.baidu.com/s" # UA伪装 headers = { # 随机返回头部信息 'User-Agent':ua.random } # 封装参数,上面的url中?可以不要,发起请求的时候会自动加上 params={ 'wd':'林高禄' } # 发起请求,返回一个响应对象 response = requests.get(url=get_url,params=params,headers=headers) # 获取响应数据, page_content = response.content.decode('utf8') print(page_content) # 把数据保存在my_bai_du.html中 with open('./my_bai_du.html', 'w', encoding='utf-8') as fp: fp.write(page_content)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
2-5:cookie
我们使用一个例子来说明,获取账号下ProcessOn的最近修改数据
直接爬肯定是不行的
所以我们要先登录,再获取账号下文件的修改记录
标记个人账号的信息的就是cookie
而在requests模块模块中,cookie存在在session中
所以我们可以使用sesson登录,这样sesson就带有登录后的cookie,再用携带cookie的sesson就能获取到账号下的修改历史数据
我们抓取到ProcessOn的登录只需要2个参数,post请求
这样就可以进行模拟登录,然后再获取想要的数据
# -*- coding: utf-8 -*- # 导入requests模块 import requests # 导入UserAgent模块 from fake_useragent import UserAgent if __name__ == "__main__": # 获取session session = requests.session(); # 实例化 UserAgent 类 ua = UserAgent() # 指定登录url url="https://www.processon.com/login" # UA伪装 headers = { # 随机返回头部信息 'User-Agent':ua.random } # 封装登录参数 params={ 'login_email': '你们的账号', 'login_password': '你们的密码' } # 发起登录请求,返回一个响应对象 response = session.post(url=url,params=params,headers=headers) # 获取响应数据 page_content = response.content.decode('utf8') # 把数据保存在my.html中 with open('./my.html', 'w', encoding='utf-8') as fp: fp.write(page_content) # 指定修改历史url url = "https://www.processon.com/folder/loadfiles" # 发起请求,session中已携带账号信息 response = session.get(url=url,headers=headers) print(response.text) # 把数据保存在my2.html中 with open('./my2.html', 'w', encoding='utf-8') as fp: fp.write(response.text)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
获取到历史修改数据
我们也可以得知结果是json数据,所以我们可以使用response.json()得到json对象
# -*- coding: utf-8 -*- # 导入requests模块 import requests # 导入UserAgent模块 from fake_useragent import UserAgent import json if __name__ == "__main__": # 获取session session = requests.session(); # 实例化 UserAgent 类 ua = UserAgent() # 指定登录url url="https://www.processon.com/login" # UA伪装 headers = { # 随机返回头部信息 'User-Agent':ua.random } # 封装登录参数 params={ 'login_email': '15103631910', 'login_password': '15103631910com' } # 发起登录请求,返回一个响应对象 response = session.post(url=url,params=params,headers=headers) # 获取响应数据 page_content = response.content.decode('utf8') # 把数据保存在my.html中 with open('./my.html', 'w', encoding='utf-8') as fp: fp.write(page_content) # 指定修改历史url url = "https://www.processon.com/folder/loadfiles" # 发起请求,session中已携带账号信息 response = session.get(url=url,headers=headers) json_data = response.json() print(json_data) # 把数据保存在my2.json中 with open('./my2.json', 'w', encoding='utf-8') as fp: # 因为是utf-8,所以ascii编码要设为False json.dump(json_data,fp=fp,ensure_ascii=False)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
结果
2-6:代理
在很多时候,我们写好的一个爬虫刚开始还可以正常的运行,也可以正常的去抓取数据,一切看起来都是那么的美好,然而,可能上个厕所回来,可能就会出现相关的错误,比如出现403等等错误,打开页面一看,可能就会出现您的IP访问频率过高等提示,出现这样的现象的原因就是因为这些对应的门户网站采取的某系反爬措施,拒绝了你的IP访问,也就是你的IP被服务器给封掉了
为了防止以上的事发生,这就需要一个IP来伪装,而不直接向门户网站的服务器暴露我们的IP,这就是代理。
所有代理,就是代理服务器,也就是我们不直接向门户网站发送请求,而是向代理服务器发送,代理服务器再将请求转发给web服务器,代理服务器拿到web服务器的响应后,再把响应返回给我们,也就是暴露给wen服务器的IP是代理服务器的IP,这样的好处是:
- 突破自身IP访问的限制
- 隐藏自身真实的IP
代理相关的网站
我们输入网址https://www.baidu.com/s?wd=ip,就能显示我们的IP
如果我们使用了代理,那么就会显示代理IP,如何使用代理,因为代理需要花钱买,本人穷困潦倒,买不起了proxies={ "https":"112.111.77.174:9999" }
- 1
- 2
- 3
- 4
然后requests(url=url,proxies=proxies)请求传入代理
https的请求使用https的代理,http的请求使用http的代理
代码示例如下# -*- coding: utf-8 -*- # 导入requests模块 import requests from fake_useragent import UserAgent ua = UserAgent() url="http://www.baidu.com/s?wd=ip" headers = { 'User-Agent':ua.random } params={ } # 代理 proxies={ "http":"112.111.77.174:9999" } response = requests.get(url=url,params=params,headers=headers,proxies=proxies) # >参数传入代理 response.encoding='utf-8' with open('./百度.html', 'w', encoding='utf-8') as fp: fp.write(response.text)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
2-7:验证码
验证码(CAPTCHA)是“Completely Automated Public Turing test to tell Computers and Humans Apart”(全自动区分计算机和人类的图灵测试)的缩写,是一种区分用户是计算机还是人的公共全自动程序。可以防止:恶意破解密码、刷票、论坛灌水,有效防止某个黑客对某一个特定注册用户用特定程序暴力破解方式进行不断的登陆尝试,实际上用验证码是现在很多网站通行的方式,我们利用比较简易的方式实现了这个功能。这个问题可以由计算机生成并评判,但是必须只有人类才能解答。由于计算机无法解答CAPTCHA的问题,所以回答出问题的用户就可以被认为是人类。
所以验证码,实际上也是反爬措施的一种,目前验证码有很多种
- 图片验证码:即数字、字母、文字、图片物体等形式的传统字符验证码
- 滑动验证码
- 图中点选
- 短信验证码
- 语音验证码
- 问题类验证码
这里面,验证码破解就不是很容易,需要下一番功夫,这就不是本篇博客的主要内容了,至于图片验证码,但是我们可以借助打码平台,比如超级鹰,打码平台会给我们例子请求,然后返回正确的验证内容
python也提供了图像识别,识别图像中的文字,得到我们的验证码,但是这个识别度不是很高,具体要很高的识别度,还得深度学习机器训练,这就涉及神经网络相关的内容了,不是我们本篇博客的内容
python提供了pytesseract模块来图像识别,这个pytesseract模块安装起来貌似有点麻烦
- pip isntall pytesseract,这个不行的话,就是你们环境缺少了的东西,百度查找啊
如现在有一张图片
然后我们图像识别一下# -*- coding: utf-8 -*- import pytesseract from PIL import Image # 此段注释的代码,可以把你们的图片验证码截图保存,然后就是图像识别里面的内容 # code_element = browser.find_element_by_id('login_cn_form') # left = code_element.location['x'] # top = code_element.location['y'] # right = left + code_element.size['width'] # bottom = top + code_element.size['height'] # im = Image.open('code.png') # im = im.crop((left, top, right, bottom)) # im.save('code.png') img = Image.open('1.png') img = img.convert('L') code = pytesseract.image_to_string(img) print(code)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
结果
3:巩固练习
在巩固练习之前,先给大家介绍一种便捷方式
找到你们爬取的链接,到这里应该都会找相关的数据链接了吧,比如这里我使用百度为例
真香,这个帮我们省了很多时间敲代码,但是这个出来的东西参数很多,这个看个人习惯哈
3-1:爬取豆瓣电影分类排行榜 - 情色片
我们先看结果页以及相关请求
我们把页条数放大为200,
# -*- coding: utf-8 -*- # 导入requests模块 import requests # 导入UserAgent模块 from fake_useragent import UserAgent if __name__ == "__main__": # 实例化 UserAgent 类 ua = UserAgent() # 指定url url="https://movie.douban.com/j/chart/top_list" # UA伪装 headers = { # 随机返回头部信息 'User-Agent':ua.random } params = { 'type':'6', 'interval_id':'100:90', 'action':'unwatched', 'start':'0', 'limit':'200' } # 发起请求,返回一个响应对象 response = requests.get(url=url,headers=headers,params=params) # 获取响应数据 page_json = response.json() for index,article in enumerate(page_json): print(str(index),article['title'],article['url'])
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
3-2:获取淘宝首页的搜索提示
我们先看结果页以及相关请求
我们先获取结果看一下,并不是json字符串,找到了一点规律,那就试着把’callback’: 'jsonp18’参数去掉
变成了json字符串,这样就可以用json解析了
# -*- coding: utf-8 -*- # 导入requests模块 import requests # 导入UserAgent模块 from fake_useragent import UserAgent import json if __name__ == "__main__": # 实例化 UserAgent 类 ua = UserAgent() # 指定url url="https://suggest.taobao.com/sug" # UA伪装 headers = { # 随机返回头部信息 'User-Agent':ua.random } params = { 'code': 'utf-8', 'q': '程序员', 'extras': '1', 'area': 'c2c', 'bucketid': 'atb_search', 'pid': 'mm_26632258_3504122_32538762', 'clk1': 'e805deeff45a8341512810a026ac44b8', '_': '1607953862548', } # 发起请求,返回一个响应对象 response = requests.get(url=url,headers=headers,params=params) json_data = json.loads(response.text) for data in json_data['result']: print(data)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
3-3:获取我房网新房列表的价格走势数据
我们先看价格某一楼盘的价格走势数据
开搞
# -*- coding: utf-8 -*- # 导入requests模块 import requests # 导入UserAgent模块 from fake_useragent import UserAgent import json if __name__ == "__main__": # 实例化 UserAgent 类 ua = UserAgent() # 指定url url="http://wofang.com/siteMgr/api/buildingHistoryPrice/v1.0/priceTrend" # UA伪装 headers = { # 随机返回头部信息 'User-Agent':ua.random } params = { 'buildingType':'1', 'buildingId':'4482', 'monthNum':'6', 'siteId':'5', 't':'1608025302194', } # 发起请求,返回一个响应对象 response = requests.get(url=url,headers=headers,params=params) json_data = json.loads(response.text) print(json_data) for data in json_data.items(): print(data)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
结果
上一步的结果,我们得到了某个楼盘的价格走势数据,要想得到所有楼盘的,那就得得到楼盘列表,我们看一下列表的访问链接和参数
盘它
# -*- coding: utf-8 -*- import requests from fake_useragent import UserAgent import json if __name__ == "__main__": ua = UserAgent() url="http://wofang.com/siteMgr/api/building/v1.0/buildingBaseList" headers = { 'User-Agent':ua.random } params = { 'isMainType':'1', 'regionCode':'460100 ', 'pageNum':'1', 'pageSize':'20', 'siteId':'5', } response = requests.get(url=url,headers=headers,params=params) json_data = json.loads(response.text) print(json_data) for data in json_data['list']: print(data)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
结果
现在我们得到了楼盘的列表数据,也得到了一个楼盘的价格走势数据,剩下的就是怎么把列表数据的价格走势拿到,那就是拿列表数据获得相关参数传给价格走势数据爬取,这样就能得到每个楼盘的价格走势数据
我们对比价格走势的传参和列表的数据,不难发现,siteId和楼盘列表的传参一样,buildingType和buildingId可以从爬取的楼盘数据中获取,而monthNum不固定,也不是非必要的,结合数据估计是月数,那么我们就传12,拿12个月的数据
这样就好办了,把爬取价格走势数据的代码封装成一个方法,传入相关参数,然后遍历列表数据,那每一个楼盘的相关数据传入价格走势的方法进行爬取即可
# -*- coding: utf-8 -*- import requests from fake_useragent import UserAgent import json def price_trend(building_type,building_id,month_num): price_trend_params = { 'buildingType': building_type, 'buildingId': building_id, 'monthNum': month_num, 'siteId': '5' } # 发起请求,返回一个响应对象 price_trend_response = requests.get(url=price_trend_url, headers=headers, params=price_trend_params) return json.loads(price_trend_response.text) if __name__ == "__main__": ua = UserAgent() url="http://wofang.com/siteMgr/api/building/v1.0/buildingBaseList" price_trend_url = "http://wofang.com/siteMgr/api/buildingHistoryPrice/v1.0/priceTrend" headers = { 'User-Agent':ua.random } params = { 'isMainType':'1', 'regionCode':'460100 ', 'pageNum':'1', 'pageSize':'20', 'siteId':'5', } response = requests.get(url=url,headers=headers,params=params) json_data = json.loads(response.text) print(json_data) for data in json_data['list']: print(data) print(price_trend(data['buildingType'],data['id'],12))
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
盘的结果
我们从前面知道,要获取用户的播放记录,就得获得用户的cookies,带着cookies去访问播放记录的url,才能获得用户的播放记录,获得用户的cookies的我们有2种方法:
- 一种是模拟用户登录,拿到带有登录后的cookies信息的session再去访问播放记录的url;
- 一种是手动在浏览器登录后,抓包工具去拿到cookies,复制出来作为参数去访问播放记录的url;
一般我们优先使用第一种,程序模拟登录,我们先看爱奇艺的登录的相关信息
开始盘它
# -*- coding: utf-8 -*- import requests from fake_useragent import UserAgent if __name__ == "__main__": ua = UserAgent() url="https://passport.iqiyi.com/apis/reglogin/login.action" headers = { 'User-Agent':ua.random } params = { 'email':'这里输入你们自己的账号', 'fromSDK':'1', 'sdk_version':'1.0.0', # 这里的密码是加密后的密码,可以用抓包工具去获取加密后的密码,或者是破解 爱奇艺的加密>方式 >'passwd':'92c06dd9a8cdc300c3a1e533bbfb4fe718c0705fdef2cbfa3cce09cd9d6369ed038520d7c2c4c52a4fb1a5707430ede80064066d0fad224e6bda5ee01a2add34', 'agenttype':'1', '__NEW':'1', 'checkExist':'1', 'ptid':'01010021010000000000', 'nr':'2', 'sports_account_merge':'1', 'verifyPhone':'1', 'area_code':'86', 'dfp':'a17a45bfe6c8a44222868f7b7a9dc6302a2659653f7f3a718989a381a4c60f659c', 'qd_sc':'8d0544b122e59d11948ff363da2e302e', } response = requests.get(url=url,headers=headers,params=params) print(response.status_code) print(response.text)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
能登录成功了,那么我们就先看一下播放记录的相关信息
开搞开搞
# -*- coding: utf-8 -*- import requests from fake_useragent
- 1
- 2
- 3
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。