Python爬虫---爬虫介绍,实战案例

news2024/11/16 1:49:43

目录标题

    • 1、爬虫介绍
      • 1.1 爬虫的合法性
      • 1.2 网络爬虫的尺寸
      • 1.3 robots.txt协议
      • 1.4 http&https协议
      • 1.5 requests模块
        • 1.5.1 request库的异常
    • 2、实战案例
      • 2.1 百度页面
      • 2.2 爬取京东商品页面
      • 2.3 爬取亚马逊商品页面-更改headers
      • 2.4 百度/360搜索关键词提交-params
      • 2.5 网络图片的爬取和存储
      • 2.6 IP地址归属地的自动查询
      • 2.7 爬取搜狗首页
      • 2.8 搜索词条
      • 2.9 破解百度翻译
      • 2.10 豆瓣电影排行
      • 2.11 爬取肯德基餐厅查询指定地点的餐厅
      • 2.12 爬取国家药品监督管理局

1、爬虫介绍

什么是爬虫?
– 通过编写程序,模拟浏览器上网,然后让其去互联网上抓取数据的过程
浏览器抓取的是一个整页面,而我们很多时候爬虫是先抓取符合特定要求的信息

1.1 爬虫的合法性

在法律中是不被禁止的,但具有违法风险
不合法:爬虫+黑客技术,攻击别人的网站
善意爬虫 -搜索引擎里的抓取系统其实就是各自编写的一个爬虫程序
恶意爬虫 - 抢票软件对12306的多次操作
爬虫类似骚扰电话,网络爬虫会对web开发带来问题

爬虫带来的风险可以体现在如下2个方面:

  • 骚扰问题:爬虫行为干扰了被访问网站的注册运营
  • 法律问题:爬虫抓取的数据用于牟利将带来法律风险

如何避免进局子?

  1. 时常优化自己的程序,避免干扰被访问网站的正常运行
  2. 在使用、传播爬取到的数据时,审查抓取到的内容,涉及用户隐私或者商业机密等敏感内容,及时停止爬取或传播

因为这些问题,网站人员会限制爬虫:

  1. 来源审查:判断User-Agent进行限制,如果User-Agent字段不是已知的浏览器,则很可能是爬虫
  2. 发布公告:Robots协议,告知可爬取的内容

1.2 网络爬虫的尺寸

在这里插入图片描述
大规模的全网爬虫,类似百度,谷歌这种浏览器,速度是关键

爬虫在使用场景中的分类
1.通用爬虫:(搜索引擎中的抓取系统重要部分)抓取的是一整张页面的数据
2.聚焦爬虫:是建立在通用爬虫的基础上。抓取的是页面中特定的局部内容。(先通用爬虫找到一页面,再聚焦爬虫找到页面中局部内容)
3.增量爬虫:监测网站中数据更新的情况。只会抓取网站中最新更新出来的数据。

爬虫中的矛与盾?
例子:电商中店家,一方面希望产品被爬取,这样会增加产品的流量。另一方面,不希望被同行爬取,或得产品价格、产品描述等详细信息

反爬机制
门户网站,通过制定相应策略或技术手段,防止爬虫程序进行网站数据的爬取。

反反爬策略
爬虫程序通过制定相关策略或技术手段,破解门户网站中的反爬机制,从而获得门户网站中的相关数据

1.3 robots.txt协议

robots-机器人
use-agent
disallow

  • —表示所有
    君子协议。规定了哪些数据可以被爬取哪些数据不可以被爬取。
    如何查看:网站地址/robots.txt
    例如:https://www.taobao.com/robots.txt
    如果网站没用robosts协议,默认允许所有爬虫

1.4 http&https协议

http协议-超文本传输协议
概念:服务器与客户端进行数据交互的一种形式。http是一种基于“请求与响应”模式的、无状态的应用层协议。
无状态是指:第一次请求与第二次请求之间没有关联
应用层协议:该工作在TCP协议之上
HTTP协议采样URL作为定位网络资源的标识
在这里插入图片描述
理解URL:通过HTTP协议存取资源的Internet路径,一个url对应一个数据资源
在这里插入图片描述
patch与put的对比:
在这里插入图片描述

常用请求头信息:
User-Agent : 请求载体的身份标识(浏览器的标识,例谷歌。)
Connection : 请求完毕后,是断开连接还是保持连接

常用响应头信息:
Content-Type :服务器响应回客户端的数据类型(可以是字符串类型,jesen类型等)

https协议:
https协议与http协议几乎类似,唯一的区别是s (secure安全)
安全的http协议,安全的超文本传输协议,安全涉及到数据加密,交互、传输过程中的数据是加密过的。

加密方式:

  • 对称密钥加密:客户端把密钥+密文发给服务器,缺点容易被截取
  • 非对称密钥加密:服务器发公钥给客户端,客户端据此加载密文后传回,缺点公钥可能会被拦截且篡改
  • 证书密钥加密(https采取的证书密钥加密):引入一个证书认证机构

1.5 requests模块

网络请求模块:urllib模块与 requests模块
requests模块:python中原生的一款基于网络请求的模块,功能强大,简单便捷,效率极高。
作用:模拟浏览器发请求。

如何使用?(requests模块的编码流程)
遵从浏览器发请求的流程

  1. 指定url (要访问的网页)
  2. 发起请求
  3. 获取响应数据
  4. 持久化存储响应数据

环境安装:pip install requests
测试:import requests

实战:

  1. 需求1:爬取搜狗指定词条对应的搜索结果页面(简易网页采集器)
    UA检测、UA伪装

  2. 需求2:破解百度翻译
    post请求(携带了参数)
    响应数据是一组json数据

  3. 需求3:爬取豆瓣电影分类排行榜中电影详情数据

request.get(url,params=None,**kwargs)
url :拟获取页面的url链接
params: 参数,字典或者字节流格式
**kwargs: 12个控制访问的参数

r.status.code —状态码。如果是200说明请求成功,否则请求失败
type® —是一个类
r.headers ----get请求获得页面的头部信息
r.text----http响应内容的字符串形式,即url对应的页面内容
r.encoding ----编码方式
r.apparent_encoding — 备选编码方式
r.content—HTTP响应内容的二进制形式
在这里插入图片描述
使用requests.get请求时的流程:
在这里插入图片描述

1.5.1 request库的异常

在这里插入图片描述
r.raise_for_status() —用来查看是否异常,如果不是200,产生requests.HTTPError异常

通用代码框架:

import requests
def getHTMLText(url):
	try:
		r = requests.get(url,timeout=30)
		r.raise_for_status() #如果不是200,产生requests.HTTPError异常
		r.encoding = r.apparent_encoding  #让编码为utf-8
		return r.text
	except:
		return "产生异常"

if __name__ =='__main__':
	url = "https://www.baidu.com"
	print(getHTMLText(url))  #正常输出内容

Requests库的7个主要方法
在这里插入图片描述
最常使用的方法:requests.get()

2、实战案例

2.1 百度页面

import requests
r = requests.get("https://www.baidu.com")
r.status_code  #输出200---正常
r.text  #输出乱码
r.encoding  #不是utf-8
r.encoding = 'utf-8'
r.text #这是输出内容出现中文,我们可读

如果header中不存在charset,则认为编码为ISO-8859-1,但这个没法解析中文

2.2 爬取京东商品页面

import requests
url = "https://item.jd.com/236897.html"   #某一个具体商品的链接
try:
	r = requests.get(url) 
	r.status_for_status()  #输出200,访问正常
	r.encoding = r.apparent_encoding
	print(r.text[:100])
except:
	print("爬取失败")

2.3 爬取亚马逊商品页面-更改headers

import requests
r = requests.get("https://www.amazon.cn/gp/product/Bo1M8L5z3Y")
r.status_code  #输出503---不正常
r.text  #输出乱码
r.encoding  #不是utf-8
r.encoding = 'utf-8'
r.text  #输出内容还是有问题
r.request.headers #头信息诚实的告诉了网站是python爬虫

kv = {'user-agent','Mozilla/5.0'} #字段写成了Mozilla/5.0一个浏览器
url = "https://www.amazon.cn/gp/product/Bo1M8L5z3Y"
r = requests.get(url,headers = kv)
r.status_code  #输出200
r.text[:1000]

2.4 百度/360搜索关键词提交-params

在这里插入图片描述

import requests
kv = {'wd':'Python'}
r = requests.get("http://www.baidu.com/s",params = kv)
r.status_code  #200
r.request.url  #输出完整的url:http://www.baidu.com/s?wd=Python
len(r.text) #太大了,先不打印

2.5 网络图片的爬取和存储

如果一个url链接是以.jpg结尾,则表示的是一个图片文件

import request
path = "D:/abc.jpg"  #保存的目标路径
url = "http://........jpg" #图片的url
r = requests.get(url)
r.status_code  #200
with open(path,'wb') as f:   #打开路径并写入
	f.write(r.content)

用图片原本的名字命名:
在这里插入图片描述
图片、视频、动画等都是类似这种

2.6 IP地址归属地的自动查询

IP138网站提供了IP地址查询归属地的功能,所以借助IP138网站

import requests
url = "http://m.ip138.com/ip.asp?ip="
r = requests.get(url+'202.204.80.112')
r.status_code  #200
r.text[-500:] #内容可能会很大,所以一般取前1000,或者后500

网站平台提供的一些点查询的功能,可能都是通过链接来实现的

2.7 爬取搜狗首页

需求:爬取搜狗首页的页面数据

#!/usr/bin/env python
# -*- coding:utf -8 -*-
#- 需求:爬取搜狗首页的页面数据
import requests
if __name__ == "__main__":
    #step 1:指定url
    url = "https://www.sogou.com/"
    #step 2:发起请求
    #get方法会返回一个响应对象
    response = requests.get(url=url)
    #step 3:获取响应数据,.text返回的是字符串形式的响应数据
    page_text = response.text  #即将该页面的编码以字符串形式返回给了page_text
    print(page_text)  #打印出来观察一下,打印出的是源码数据
    #step 4:持久化存储响应数据
    #搜狗首页的源码数据存储在当前地址的sogou.html文件中
    with open('./sogou.html','w',encoding= 'utf-8') as fp:
        fp.write(page_text)
    print('爬取数据结束!!!')

结束后点击文件夹中的sogou.html项目,加载出来的网页即爬出来的页面

2.8 搜索词条

需求1:爬取搜狗指定词条对应的搜索结果页面(简易网页采集器)

#!/usr/bin/env python
# -*- coding:utf-8 -*-

#UA:User-Agent(请求载体的身份标识)
#UA伪装 :门户网站的服务器会检测对应请求的载体身份标识,
# 如果检测到请求的载体身份标识为某一款浏览器,说明该请求是一个正常请求。但是。。
#但是如果检测到请求的载体身份标识不是基于某一款浏览器的,则表示该请求为不正常的请求(即是爬虫)则服务器很有可能会拒绝此请求
#所以,每次爬虫中要进行UA伪装,这一反爬
#UA伪装:让爬虫对应的请求载体身份标识伪装成某一款浏览器
import requests
if __name__ == "__main__":
    #UA伪装:将对应的USer-Agent 封装到一个字典中
    #headers封装的是一个基于谷歌浏览器的
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36'
    }
    url = 'https://www.sogou.com/web?'
    #处理url携带的参数:封装到字典中
    kw = input('enter a word:')
    param = {
        'query':kw
    }
    #对指定的url发起的请求对应的url是携带参数的,并且请求过程中处理了参数
    response=requests.get(url = url,params=param,headers = headers) #动态拼接params参数

    page_text = response.text
    fileName = kw+'.html'
    with open(fileName,'w',encoding='utf-8') as fp:
        fp.write(page_text)
    print(fileName,'保存成功!!!')

输入自己想要查询的关键词,爬取出浏览器搜索出的结果页面

2.9 破解百度翻译

数据解析:一张页面中的局部解析
局部页面刷新:
post请求(携带了参数)

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import requests
import json
if __name__ == '__main__':
    #1,指定url
    post_url = 'https://fanyi.baidu.com/sug'
    #2,请求前进行UA伪装
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36'
    }
    #3,post请求参数处理(同get请求一致)
    word = input('enter a word:')
    data = {
        'kw':'word'
    }

    #4,请求发送
    response = requests.post(url = post_url,data = data,headers = headers)
    #5,获取相应数据
    # 本例中拿到json数据,json()方法返回的是obj。只有确认拿到的响应数据是json类型时,才可以用json()(看Content-Type: application/json)
    dic_obj = response.json()


    #持久化存储
    fileName = word + '.json'
    fp = open(fileName,'w',encoding='utf-8')
    json.dump(dic_obj,fp=fp,ensure_ascii=False)#ensure_ascii拿到的是中午,不能用ascii
    print('over!!')

2.10 豆瓣电影排行

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import requests
import json
#滑动页面,会刷新页面---json数据
#Content-Type: application/json; ---确定是json数据
if __name__=='__main__':
    url = 'https://movie.douban.com/j/chart/top_list'
    #url 复制过来,但是字典形式要重新封装
    param = {
        'type': 24,
        'interval_id': '100:90',
        'action':'',
        'start': 0,  #从库中第几部电影开始取,从0开始
        'limit': 20,   #一次取出的个数
    }
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36'
    }
    response = requests.get(url=url,params = param,headers=headers)
    list_data = response.json()
    fp = open('./douban.json','w',encoding='utf-8')
    json.dump(list_data,fp=fp,ensure_ascii=False)
    print('over!!')

2.11 爬取肯德基餐厅查询指定地点的餐厅

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import requests
import json
#滑动页面,会刷新页面---json数据
#Content-Type: application/json; ---确定是json数据
if __name__=='__main__':
    url = 'http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=keyword'
    kw = input('enter a word:')
    param = {
        'cname':'',
        'pid':'',
        'keyword': kw,
        'pageIndex': 1,
        'pageSize': 10,
    }
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36'
    }
    response = requests.get(url=url,params = param,headers=headers)
    page_text = response.text
    fileName = kw+'.html'  #存入文件的文件名
    with open(fileName,'w',encoding='utf-8') as fp:
        fp.write(page_text)
    print(fileName,'保存成功!!!')

有点不理解,为啥这里url的问号后面部分不删掉?

2.12 爬取国家药品监督管理局

网站设置了新的反爬机制,无法实际爬到,但思路仍然值得学习

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import requests
if __name__ = "__main__":
	url = ''
	headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36'
    }
    response = requests.get(url=url,params = param,headers=headers)
    page_text = response.text
    with open('./huazhuangpin.html','w',encoding='utf-8') as fp:
    	fp.write(page_text)
    

代码测试or抓包工具,得到不是由于地址栏中的url得到的。可能是由于ajax请求得到的
XHR中的ajax请求包
通过对详情页的url分析得到:

  1. url的域名都是一样的,只有携带的参数id不一样
  2. id值可以从首页对应的ajax请求到的json中获取
  3. 域名和id值拼接出一个完整的详情页的url
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import requests
if __name__ ="__main__":
	url = '首页的url'
	data = {
		参数键值形式}
	headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36'
    }
    id_list=[]#存储企业的id
    all_Data_list = []#存储所有的企业详情数据
    json_jds = requests.post(url=url,params = param,headers=headers).json()
    #json_jds字典形式,从其中获取id
    for dic in json_ids['list']:
    	id_list.append(dic['ID'])
    
    #获取企业的详情
    post_url = '详情页的url'
    for id in id_list:
    	data = {
    		'id':id}
    	detail_json = requests.post(url=url,params = param,headers=headers).json()
    	#print(detail_json,'-----ending-----')
    	all_data_list.append(detail_json)
	#持久化存储all_data_list
	fp = open('./allData.json','w',encoding='utf-8')
	json.dump(all_data_list,fp=fp,ensure_ascii=False)
	print('over!!')
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/173770.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Nacos 报Statement cancelled due to timeout or client request

1. 问题:nacos 启动报错,启动失败,全部报错下面贴出。 2. 结论:排查结果为服务器带宽不够,mysql 查询的数量量太大,传输时间损坏在网络io上! 3. 下面开始回溯事故起因: 前期config…

2022年一年级入学小结

2022年即将过去,在这里,简单回顾一下Richard同学进入小学一学期后的成长经历和小结。先说说学校生活Richard很喜欢目前的学校,喜爱给他授课的每一位老师,也和老师和同学们相处得不错,自诩自己现在的”粉丝“蛮多。从我…

C++设计模式(6)——适配器模式

亦称: 封装器模式、Wrapper、Adapter 意图 适配器模式是一种结构型设计模式, 它能使接口不兼容的对象能够相互合作。 问题 假如你正在开发一款股票市场监测程序, 它会从不同来源下载 XML 格式的股票数据, 然后向用户呈现出美…

9.框架SpringMVC

一、基本概念 Spring MVC 是 Spring 提供的一个基于 MVC 设计模式的轻量级 Web 开发框架,本质上相当于 Servlet。Spring MVC 使用 MVC 架构模式的思想,将 Web 应用进行职责解构,把一个复杂的 Web 应用划分成模型(Model&#xff09…

HashMap的使用:put、remove和get方法原理

关联项目需求进行FeatureAB上报的时候,我们使用HashSet的add方法存key值,如果key已存在,则add失败,返回false,如果key不存在,add成功,返回true。看源码中HashSet的add(E e)方法实现:…

【Git】IDEA 集成 GitHub

8、IDEA 集成 GitHub 8.1、设置 GitHub 账号 如果出现 401 等情况连接不上的,是因为网络原因,可以使用以下方式连接: 然后去 GitHub 账户上设置 token。 点击生成 token。 复制红框中的字符串到 idea 中。 点击登录。 8.2、分享工程到 GitHu…

【甄选靶场】Vulnhub百个项目渗透——项目五十五:SP-LEOPOLD v1.2(beef联动msf,脏牛提权)

Vulnhub百个项目渗透 Vulnhub百个项目渗透——项目五十五:SP-LEOPOLD v1.2(beef联动msf,脏牛提权) 🔥系列专栏:Vulnhub百个项目渗透 🎉欢迎关注🔎点赞👍收藏⭐️留言&am…

ZooKeeper-集群搭建

5)ZooKeeper 集群搭建 5.1)Zookeeper集群介绍 Leader选举: •Serverid:服务器ID 比如有三台服务器,编号分别是1,2,3。 编号越大在选择算法中的权重越大。 •Zxid:数据ID 服务器中存放的最大数据ID.值越大说明数据 越新&…

剑指offer—day1.用两个栈实现队列、包含min函数的栈

1.用两个栈实现队列 本题来源:力扣 剑指 Offer 09. 用两个栈实现队列 - 力扣(LeetCode)https://leetcode.cn/problems/yong-liang-ge-zhan-shi-xian-dui-lie-lcof/题目描述 用两个栈实现一个队列。队列的声明如下,请实现它的两…

IP-guard如何映射到外网登录访问管理

终端安全管理(endpoint security management)是一种保护网络安全的策略式方法,它需要终端设备在得到访问网络资源的许可之前遵从特定的标准。随着企业信息化发展,终端安全管理系统需求不断扩大,相关系统软件被广泛应用。 IPguard即IP-guard&a…

线段树(重要!多加理解懒惰标记!)

基础概念: 线段(区间)[L,R] 所对应的线段树是由区间 [L,R] 及其子区间构成的二叉树(如下图所示) 线段树具有的特性: (1)线段树的叶结点为只有一个元素的区间,因此长度为…

最新版海豚调度dolphinscheduler-3.1.3安装部署详细教程

0 背景 本文基于Ambari集群搭建最新版本的海豚调度dolphinscheduler-3.1.3版本,后续会尝试整合到Ambari中。 1 安装准备 安装dolphinscheduler需要在环境中安装如下依赖 ① JDK8 下载JDK (1.8),安装并配置 JAVA_HOME 环境变量,并将其下的 …

用 22 张照片打开 23 年

魔幻又带有现实主义色彩的三年似乎终将见底。这也为 2023 年赋予了一些新的意义,或许是充满生机、怀揣希望、满怀爱意,或许是重新启航、步履不停、勇敢探索……为此,我们收集了 22 位社区用户和公司小伙伴在过去一年的「特别 Moment」及新年愿…

你认为DAO是否可行?新年计划,卯足干劲,兔必No.1

文章目录🌟 课前小差🌟 聚沙成塔🌟 社会价值🌟 DAO是什么🌟 国产化🌟 商业化回报🌟 写在最后🌟 课前小差 哈喽,大家好,我是几何心凉,这是一份全新…

Spring高级之BeanFactory功能

首先,我们想要知道一个接口有哪些功能,就必须要看这个接口的源代码,在idea中,选中这个接口CtrlF12,来查看这个接口里面有哪些方法: 表面上来看,功能其实很少,查看源码及其方法功能 …

来吧,Jenkins+git+mvn+shell一键部署实践起来

环境:centosJenkins-2.319系统自带gitmvn3.8.7jdk1.8一、安装jdk1、https://blog.csdn.net/codedz/article/details/124044974centos自带了openjdk,我是选择自己重新搞一个,用的上面链接地址的yum安装方式2、安装完成查看版本查看java安装路径…

优思学院|质量人对控制图中的规格线和控制线傻傻分不清?

质量人、六西格玛[1]人和很多不同类型的工程师都需要了解什么是控制图,而在控制图中的规格限制(Specification Limit)"和"控制限制(Control Limit)"原来对好多人来说都是傻傻分不清! 规格限…

线段树入门

对于一个区间进行询问,进行修改,都是用线段树进行处理。线段树和普通的树不一样,普通的树的节点存的是一个编号,线段树存的是一个区间,而且线段树一定是一棵完全二叉树。例如:这就是一棵线段树。例如对于[1…

【Ajax】数据交换格式XML 和 JSON

一、什么是数据交换格式数据交换格式,就是服务器端与客户端之间进行数据传输与交换的格式。前端领域,经常提及的两种数据交换格式分别是 XML 和 JSON。其中 XML 用的非常少,所以,我们重点要学习的数据交换格式就是 JSON。二、XML1…

让交互更加生动!巧用CSS实现鼠标跟随 3D 旋转效果

简单分析一下,这个交互效果主要有两个核心: 借助了 CSS 3D 的能力 元素的旋转需要和鼠标的移动相结合 本人简单的说一下如何使用纯 CSS 实现类似的交互效果,以及,借助 JavaScript 绑定鼠标事件,快速还原上述效果。 …