爬虫入门到精通_基础篇1(爬虫基本原理讲解, Urllib库基本使用)

news2024/11/25 14:28:21

01 爬虫基本原理讲解

1.什么是爬虫:请求网站并提取数据的自动化程序

2.爬虫基本流程:

  1. 发起请求:通过HTTP库向目标站点发起请求,即发送一个Request,请求可以包含额外的headers等信息,等待服务器响应。
  2. 获取响应内容:如果服务器能正常响应,会得到一个Response,Response的内容便是所要获取的页面内容,类型可能有HTML,Json字符串,二进制数据(如图片视频)等类型。
  3. 解析内容:得到的内容可能是HTML,可以用正则表达式,网页解析库进行解析。可能是Json,可以直接转换为Json对象解析,可能是二进制数据,可以做保存或者进一步的处理。
  4. 保存内容:保存形式多样,可以存为文本,也可以保存至数据库,或者保存特定格式的文件。

3.Request与Response:

在这里插入图片描述

  1. 浏览器就发送消息给该网址所在的服务器,这个过程叫做HTTP Request。
  2. 服务器收到浏览器发送的消息后,能够根据浏览器发送消息的内容,做相应处理,然后把消息回传给浏览器。这个过程叫做HTTP Response。
  3. 浏览器收到服务器的Response信息后,会对信息进行相应处理,然后展示。

4.request包含的内容

  1. 请求方式:主要有GET,POST两种类型,另外还有HEAD,PUT,DELETE,OPTIONS等。
  2. 请求头:包含请求时的头部信息,如User-Agent,Host,Cookies等信息。
  3. 请求URL:URL全称统一资源定位符,如一个网页文档,一张图片,一个视频等都可以用URL唯一来确定。
  4. 请求体:请求时额外携带的数据,如表单提交时的表单数据。

5.Resopnse包含的内容

  1. 响应状态:有多种响应状态,如200代表成功,301跳转,404找不到页面,502服务器错误。
  2. 响应头:如内容类型,内容长度,服务器信息,设置Cookie等等。
  3. 响应体:最注意的部分,包含了请求资源的内容,如网页HTML,图片二进制数据等。

6.能抓怎样的数据?

  1. 网页文本:如HTML文档,Json格式文本等。
  2. 图片:获取到的是二进制文件,保存为图片格式。
  3. 视频:同为二进制文件,保存为视频格式即可。
  4. 其他:只有是能请求到的,都能获取。

7.解析方式

  1. 直接处理
  2. Json解析
  3. 正则表达式
  4. BeautifulSoup
  5. PyQuery
  6. XPath

8.怎么解决JavaScript渲染的问题?(后台请求和实际看到不一样时)

  • 分析Ajax请求
  • Selenium/WebDriver
  • Splash
  • PyV8,Ghost.py

9.怎么保存数据?

  • 文本:纯文本,Json,Xml等。
  • 关系型数据库:如MySQL,Oracle,SQL Server等具有结构化表结构形式存储。
  • 非关系型数据库:如MongoDB,Redis等Key-Value形式存储。
  • 二进制文件:如图片,视频,音频等等直接保存成特定格式即可。

02 Urllib库基本使用

1.Urllib库详解(python内置的HTTP请求库)

  • urllib.request 请求模块
  • urllib.error 异常处理模块
  • urllib.parse url解析模块
  • urllib.robotparser robots.txt解析模块

2.相比python2变化

Python2

import urllib2
response = urllib2.urlopen('http://www.baidu.com')

Python3

import urllib.request
respnse = urllib.request.urlopen('http://www.baidu.com')

3.urlopen:函数用于实现对目标url的访问

urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)

  • url 参数:目标资源在网路中的位置。可以是一个表示URL的字符串(如:http://www.pythontab.com/);也可以是一个urllib.request对象,详细介绍请跳转.
  • data参数:data用来指明发往服务器请求中的额外的参数信息(如:在线翻译,在线答题等提交的内容),data默认是None,此时以GET方式发送请求;当用户给出data参数的时候,改为POST方式发送请求。
  • timeout:设置网站的访问超时时间。
  • cafile、capath、cadefault 参数:用于实现可信任的CA证书的HTTP请求。(基本上很少用)
  • context参数:实现SSL加密传输。(基本上很少用)
import urllib.request

response = urllib.request.urlopen("http://www.baidu.com")
print(response.read().decode('utf-8'))

post请求:
ttp://httpbin.org HTTP测试的网址

import urllib.parse
import urllib.request

data = bytes(urllib.parse.urlencode(('world','hello')),encodeing='utf8')
response = urllib.request.urlopen("http://httpbin.org/post",data=data)
print(response.read())

超时的设置:

import urllib.request

response = urllib.request.urlopen("http://httpbin.org/get",timeout=1)
print(response.read().decode('utf-8'))
import socket
import urllib.request
import urllib.error

try:
	response = urllib.request.urlopen("http://httpbin.org/get",timeout=0.1)
except urllib.error.URLError ad e:
	if isinstance(e.reason,socket.timeout);
		print("TIME OUT")

4.响应

响应类型

import urllib.request

response = urllib.request.urlopen("http://httpbin.org")
print(type(response))

在这里插入图片描述

状态码,响应头

import urllib.request

response = urllib.request.urlopen("http://httpbin.org")
print(response.status)
print(response.getheaders())
print(response.getheader('Server'))

在这里插入图片描述

响应内容

import urllib.request

response = urllib.request.urlopen("http://httpbin.org")
print(response.read().decode('utf-8'))

在这里插入图片描述
想要一些更复杂的请求,需要用到request

5 Request

urllib.request.Request(url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None)

  • url用于请求URL,这是必传参数,其他都是可选参数。
  • data如果要传,必须传bytes(字节流)类型的。如果它是字典,可以先用urllib.parse模块里的urlencode()编码。
  • headers是一个字典,它就是请求头,我们可以在构造请求时通过headers参数直接构造,也可以通过调用请求实例add_header()方法添加。
    添加请求头最常用的用法就是通过修改User-Agent来伪装浏览器,默认的User-Agent是Python-urllib,我们可以通过修改它来伪装浏览器。
  • origin_req_host指的是请求方的host名称或者IP地址。
  • unverifiable表示这个请求是否是无法验证的,默认是False,意思就是说用户没有足够权限来选择接收这个请求的结果。例如,我们请求一个HTML文档中的图片,但是我们没有自动抓取图像的权限,这时unverifiable的值就是True`。
  • method是一个字符串,用来指示请求使用的方法,比如GET、POST和PUT等。
import urllib.request

request  = urllib.request.Request("https://python.org")
response = urllib.request.urlopen(request)
print(response.read().decode('utf-8'))

在这里插入图片描述

增加headers信息:

from urllib import request, parse
 
url = 'http://httpbin.org/post'
headers = {
    'User-Agent': 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)',
    'Host': 'httpbin.org'
}
dict = {
    'name': 'Germey'
}
data = bytes(parse.urlencode(dict), encoding='utf8')
req = request.Request(url=url, data=data, headers=headers, method='POST')
response = request.urlopen(req)
print(response.read().decode('utf-8'))

在这里插入图片描述
通过4个参数构造了一个请求,其中url即请求URL,headers中指定了User-Agent和Host,参数data用urlencode()和bytes()方法转成字节流。另外,指定了请求方式为POST。

from urllib import request,parse
#构造一个POST请求
url='http://httpbin.org/post'
dict={
	'name':'Germey'
}
data=bytes(parse.urlencode(dict),encoding='utf8')#fontdata数据
req=request.Request(url=url,data=data,method='POST')#构建一个Request()的一个结构
req.add_header('User-Agent','................')#用add_header方法来添加header信息
response = request.urlopen(req)
print(response.read().decode('utf-8'))

add_header()方法作为添加header的另一种方式,可以用来比较复杂的情况,比如要添加许多键值对,那么可以用一个for循环来不断调用这个方法,这也是比较方便的
在这里插入图片描述

6.Handler

Headler相当于一个辅助工具,来帮助我们处理一些额外的工作,比如FTP、Cache等等操作,我们都需要借助Headler来实现。比如在代理设置的时候,就需要用到一个ProxyHandler。更多的用法,请参阅官方文档。

代理

用来对ip地址进行伪装成不同地域的,防止ip在爬虫运行时被封掉。

from urllib import request
proxy_handler = request.ProxyHandler( #构建ProxyHandler,传入代理的网址
{'http':'http://127.0.0.1:9743',
'https':'https://127.0.0.1:9743'
}) #实践表明这个端口已经被封了,这里无法演示了
 
opener = request.build_opener(proxy_handler)#再构建一个带有Handler的opener
 
response = opener.open('http://www.baidu.com')
print(response.read())

Cookie

Cookie是在客户端保存的用来记录用户身份的文本文件。
在爬虫时,主要是用来维护登录状态,这样就可以爬取一些需要登录认证的网页了。
在这里插入图片描述

from urllib import request
 
from http import cookiejar
cookie =cookiejar.CookieJar()#将cookie声明为一个CookieJar对象 
handler = request.HTTPCookieProcessor(cookie)
opener = request.build_opener(handler)
response  =opener.open('https://www.hao123.com')#通过opener传入,并打开网页
 
for item in cookie:#通过遍历把已经赋值的cookie打印出来
    print(item.name+'='+item.value)#通过item拿到每一个cookie并打印

在这里插入图片描述

Cookie的保存

我们还可以把cookie保存成文本文件,若cookie没有失效,我们可以从文本文件中再次读取cookie,在请求时把cookie附加进去,这样就可以继续保持登录状态了。

from urllib import request
from http import cookiejar

filename="cookie.txt"
cookie=cookiejar.MozillaCookieJar(filename)
#把cookie声明为cookiejar的一个子类对象————MozillaCookieJar,它带有一个save方法,可以把cookie保存为文本文件
handler=request.HTTPCookieProcessor(cookie)
opener=request.build_opener(handler)
response=opener.open('https://www.hao123.com')
cookie.save(ignore_discard=True,ignore_expires=True)#调用save方法

执行代码后,我们就可以在运行目录下找到已经保存好的cookie文本文件了:
在这里插入图片描述
还有另外一种格式:
在上面那段代码的基础上,换一个子类对象就可以了:

cookie=cookiejar.LWPCookieJar(filename)

from urllib import request
from http import cookiejar

filename="cookie.txt"
cookie=cookiejar.LWPCookieJar(filename)
#把cookie声明为cookiejar的一个子类对象————MozillaCookieJar,它带有一个save方法,可以把cookie保存为文本文件
handler=request.HTTPCookieProcessor(cookie)
opener=request.build_opener(handler)
response=opener.open('https://www.hao123.com')
cookie.save(ignore_discard=True,ignore_expires=True)#调用save方法

在这里插入图片描述

Cookie的读取

我们可以选择相对应的格式来完成读取。以上面的LWP格式为例:

from urllib import request
from http import cookiejar

cookie=cookiejar.LWPCookieJar() #z注意选择相应的格式,这里是LWP
cookie.load('cookie.txt',ignore_discard=True,ignore_expires=True)#load方法是读取的关键
handler=request.HTTPCookieProcessor(cookie)
opener=request.build_opener(handler)
response=opener.open('http://www.baidu.com')
print(response.read().decode('utf-8'))

以上的代码就可以完成读取了。这样,我们就可以在对网页进行请求时,自动把之前的cookie附着进去,以保持一个登录的状态了。

7.异常处理

这是属于urllib的另一大模块

from urllib import request,error

#我们试着访问一个不存在的网址
try:
    response = request.urlopen('http://www.cuiqingcai.com/index.html')
except error.URLError as e:
    print(e.reason)#通过审查可以查到我们捕捉的异常是否与之相符

在这里插入图片描述
可以看到,返回了错误信息。这样的异常处理可以保证爬虫在工作时不会轻易中断。
那么,urllib可以捕捉哪些异常呢?详见官方文档。
其实一般碰到有两个:HTTP和URL。我们一般只需要捕捉这两个异常就可以了。

from urllib import request,error

#我们试着访问一个不存在的网址
try:
    response = request.urlopen('http://www.cuiqingcai.com/index.html')
except error.HTTPError as e:#最好先捕捉HTTP异常,因为这个异常是URL异常的子类
	print(e.reason,e.code,e.headers,sep='\n')
except error.URLError as e:
    print(e.reason)
else:
	print('Request Successfully!')

在这里插入图片描述
如上,打印出了错误的相关信息。
此外,e.reason也是一个类,它可以得到异常的类型。
我们试着看看:

from urllib import request,error
import socket

try:
    response = request.urlopen('http://www.baidu.com',timeout = 0.01)#超时异常
except error.URLError as e:
    print(type(e.reason))
    if isinstance(e.reason,socket.timeout):#判断error类型
        print('TIME OUT')

在这里插入图片描述

8.URL解析

这是一个工具性质的模块,即拿即用就行。
官方文档

urlparse

这个方法将将url进行分割,分割成好几个部分,再依次将其复制。

urllib.parse.urlparse(urlstring,scheme=‘’,allow_fragments = True)
#分割成(url,协议类型,和#后面的东西)

urllib.parse.urlparse将一个url解析成6个组件,返回一个6个项目名元组:scheme(协议), netloc(域名), path(相对路径),params(参数), query(请求), fragment(片段识别)

来看具体的例子:

from urllib.parse import urlparse

result = urlparse('https://www.baidu.com/s?wd=urllib&ie=UTF-8')
print(type(result), result)  # <class 'urllib.parse.ParseResult'>

# 无协议类型指定,自行添加的情况
result1 = urlparse('www.baidu.com/s?wd=urllib&ie=UTF-8', scheme='https')
print(result1)

# 有指定协议类型,默认添加的情况?
result2 = urlparse('http://www.baidu.com/s?wd=urllib&ie=UTF-8', scheme='https')
print(result2)

# allow_fragments参数使用
result3 = urlparse('http://www.baidu.com/s?#comment', allow_fragments=False)
print(result3)

result4 = urlparse('http://www.baidu.com/s?wd=urllib&ie=UTF-8#comment', allow_fragments=False)
print(result4)
# allow_fragments=False表示#后面的东西不能填,原本在fragment位置的参数就会往上一个位置拼接,可以对比result1和result2的区别

在这里插入图片描述
从这个例子我们也可以知道,一个url可以分成6个字段。

urlunparse(urlparse的反函数)

这个函数用来拼接url。
看看这个例子:

from urllib.parse import urlunparse
#注意即使是空符号也要写进去,不然会出错

data = ['http',  'www.baidu.com', 'index.html','user','a=6' 'comment',' ']
print(urlunparse(data))

在这里插入图片描述

urljoin

这个函数用来拼合url。
通过例子感受以下:
以后面的参数为基准,会覆盖掉前面的字段。如果后面的url,存在空字段而前面的url有这个字段,就会用前面的作为补充。

from urllib.parse import urljoin
print(urljoin('http://www.baidu.com','FQA.html'))
#http://www.baidu.com/FQA.html
 
print(urljoin('http://www.baidu.com','http://www.caiqingcai.com/FQA.html'))
#http://www.caiqingcai.com/FQA.html
 
print(urljoin('https://www.baidu.com/about.html','http://www.caiqingcai.com/FQA.html'))
#http://www.caiqingcai.com/FQA.html
 
print(urljoin('http://www.baidu.com/about.html','https://www.caiqingcai.com/FQA.html'))
#https://www.caiqingcai.com/FQA.html

urlencode

from urllib.parse import urlencode

params = {
    'name': 'zhuzhu',
    'age': '23'
}
base_url = 'http://www.baidu.com?'
url = base_url + urlencode(params)  # 将params对象编码转换
print(url)

在这里插入图片描述

9.robotparser

用来解析robot.txt。用的比较少,这里不再赘述。详情参考

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

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

相关文章

python实现归并排序

归并排序 归并排序是采用分治法的一个非常典型的应用。归并排序的思想就是先递归分解数组&#xff0c;拍好各数组的顺序&#xff0c;再合并数组。 将数组分解最小之后&#xff0c;然后合并两个有序数组&#xff0c;基本思路是比较两个数组的最前面的数&#xff0c;谁小就先取…

银行常用操作指引:浦发

文章目录 引言浦发2.1 设置查询密码2.2 微信公众号绑定2.3 查询卡转账额度II 其他银行常用操作see also引言 浦发 2.1 设置查询密码 2.2 微信公众号绑定 入口:点击菜单的微信通知 用途:查询余额和明细 口令:解除绑定 2.3 查询卡转账额度 II 其他银行常用操作

06 栈

目录 1.栈 2.实现 3.OJ题 1. 栈 1. 栈的概念和结构 栈: 这一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈底。栈中的数据元素遵守后进先出LIFO&#xff08;Last In First Out&…

OSS存储引擎如何使用以及如何添加图片【建议收藏】

Aliyun OSS对象存储&#xff0c;可以用来做文件服务器&#xff0c;存放一些文件&#xff0c;图片等资源&#xff0c;那么我们使用OSS&#xff0c;需要经历以下步骤&#xff1a; 这里就从如何开通OSS服务开始进行&#xff0c;到如何上传一个资源文件到OSS结束。 1、阿里云注册 …

最新AI系统ChatGPT网站系统源码,支持AI绘画,GPT语音对话,ChatFile文档对话总结,DALL-E3文生图,MJ绘画局部编辑重绘

一、前言 SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;那么如何搭建部署AI创作ChatGPT&#xff1f;小编这里写一个详细图文教程吧。已支持GPT…

Python中==和is有什么区别

是比较两个对象的内容是否相等&#xff0c;即两个对象的“值”是否相等&#xff0c;不管两者在内存中的引用地址是否一样。 is 比较的是两个实例对象是不是完全相同&#xff0c;它们是不是同一个对象&#xff0c;占用的内存地址是否相同。即is比较两个条件&#xff1a;1.内容相…

LeetCode670.最大交换

我真的怀疑他是不是难度等级评错了&#xff0c;因为感觉没到中级&#xff0c;总之先看题吧 给定一个非负整数&#xff0c;你至多可以交换一次数字中的任意两位。返回你能得到的最大值。 示例 1 : 输入: 2736 输出: 7236 解释: 交换数字2和数字7。示例 2 : 输入: 9973 输出:…

数字拆分--完全背包问题

一、题目 https://acm.ecnu.edu.cn/problem/3034/ 二、思路 本来算法就很弱&#xff0c;加上很久没刷题&#xff0c;做这道题真的是一言难尽~ 一开始我以为是找规律写递推式&#xff0c;写到f(9)的时候就觉得不对劲&#xff0c;又想了一会&#xff0c;还是没想到&#xff0…

【Linux配置yum源以及基本yum指令】

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言 一、yum是什么&#xff1f; 二、什么是软件包&#xff1f; 三、三种安装软件包的方式 四、yum的相关操作 4.1、搜索软件 4.2、安装软件 4.3、卸载软件 4.4、那…

Python | 七、栈 Stack、队列 Queue

栈的基础知识 是一种数据结构&#xff0c;在Python中常使用列表来模拟实现特点&#xff1a;先进后出 栈的基本操作 因为Python中通过列表模拟实现栈&#xff0c;所以以下的基本操作实际是列表的一些操作获取长度&#xff0c;使用len(stack)方法进栈&#xff0c;使用stack.app…

Element组件完整引入、按需引入、样式修改(全局、局部)、简单安装less以及npm命令证书过期等

目录 一、npm 安装二、完整引入三、按需引入四、样式修改1.按需加载的全局样式修改2. 局部样式修改1. 在 css 预处理器如 less scss 等直接使用::v-deep2. 只能用在原生 CSS 语法中:/deep/ 或者 >>> 五、 拓展&#xff1a;npm 安装less报错&#xff0c;提示证书过期六…

使用Go语言编写简单的HTTP服务器

在Go语言中&#xff0c;我们可以使用标准库中的"net/http"包来编写HTTP服务器。下面是一个简单的示例&#xff0c;展示了如何使用Go编写一个基本的HTTP服务器。 go复制代码 package main import ( "fmt" "net/http" ) …

红黑树浅浅学习

红黑树浅浅学习 红黑树概念红黑树平衡性调整 红黑树概念 二叉树&#xff1a;二叉树是每个节点最多有两个子树的树结构。二叉查找树&#xff1a;又称“二叉搜索树”&#xff0c;左孩子比父节点小&#xff0c;右孩子比父节点大&#xff0c;还有一个特性就是”中序遍历“可以让结…

机器学习实验报告——Bayes算法

目录 一、算法介绍 1.1算法背景 1.2算法假设 1.3 贝叶斯与朴素贝叶斯 1.4算法原理 二、算法推导 2.1朴素贝叶斯介绍 2.2朴素贝叶斯算法推导 2.2.1先验后验概率 2.2.2条件概率公式 2.3 独立性假设 2.4 朴素贝叶斯推导 三、算法实现 3.1数据集描述 3.2代码实现 四…

python04-变量命名规则

python需要使用标识符来给变量命名。 标识符&#xff0c;我来解释下&#xff0c;就是给程序中变量、类、方法命名的符号&#xff0c;简单理解就是起一个名字&#xff0c;这个名字必须是合法的名字&#xff0c; 对于Python来说&#xff0c;标识符必须是以字母、下划线(_)开头&…

性能优化-高通的Hexagon DSP和NPU

原文来自【 Qualcomm’s Hexagon DSP, and now, NPU 】 本文主要介绍Qualcomm Hexagon DSP和NPU&#xff0c;这些为处理简单大量运算而设计的硬件。 &#x1f3ac;个人简介&#xff1a;一个全栈工程师的升级之路&#xff01; &#x1f4cb;个人专栏&#xff1a;高性能&#xf…

[足式机器人]Part2 Dr. CAN学习笔记- 最优控制Optimal Control Ch07-2 动态规划 Dynamic Programming

本文仅供学习使用 本文参考&#xff1a; B站&#xff1a;DR_CAN Dr. CAN学习笔记 - 最优控制Optimal Control Ch07-2 动态规划 Dynamic Programming 1. 基本概念2. 代码详解3. 简单一维案例 1. 基本概念 Richoard Bell man 最优化理论&#xff1a; An optimal policy has the …

Python + Selenium —— 常用控制方法!

Selenium 体系中用来操作浏览器的 API 就是 WebDriver&#xff0c;WebDriver 针对多种语言都实现了一套 API&#xff0c;支持多种编程语言。 Selenium 通常用来做自动化测试&#xff0c;或者编写网络爬虫。 通常我们说的 Selenium 自动化操作&#xff0c;指的就是 WebDriver …

LLM:RoPE - 开源代码中的实现 (下)

本文着重学习一下开源代码中关于RoPE的实现:ChatGLM-6B、ChatGLM2-6B、LLAMA 回顾一下RoPE位置编码: 1:对于 token 序列中的每个词嵌入向量,首先计算其对应的 query 和 key 向量 2:然后对每个 token 位置都计算对应的旋转位置编码 3:接着对每个 token 位置的 query 和 …

聊聊呼声较高的向量过滤搜索及其优化

向量过滤搜索是一种基于条件的向量搜索方法&#xff0c;常用于推荐系统和信息检索等领域&#xff0c;能够帮助用户快速找到在给定条件下与其查询相关的内容。 在 Milvus 社区中&#xff0c;这也是呼声比较高的功能。为满足广大用户的需求&#xff0c;Milvus 在 Knowhere 2.x 版…