[华为云在线课程][Python网络爬虫][爬虫实现流程和工具][二][学习笔记]
1.爬虫实现流程
1.1.爬虫常用的工具
HTTP请求工具库:http.client,urllib,requests。
爬虫框架:Scrapy,Scrapy-Redis,PySpider。
其他工具:Selenium,chromediriver。
1.2.爬虫工作的流程
URL:统一资源定位符,网址。
爬虫的工作过程大概可以总结为:发送请求->获取相应->提取数据。
1.3.爬虫程序的实现步骤
- 确定URL
网址范围确定,因为网页中存在很多其他网页的链接,这些链接中有一部分并不是当前网站内的链接,或者并不是我们获取数据所需的链接。 - 网页分析
网页分析:动态网页还是静态页面。
URL分析:在获取数据时,存在翻页的操作,翻页后的URL往往存在着规律。动态加载数据的网页可以通过直接查找数据对应的URL即可。
数据分析:通过网页源代码查看数据的位置,定位数据后使用工具获取。 - 工具选取
Requests,urllib等HTTP请求工具。
Scrapy,PySpider框架。 - 反爬
代理IP
Headers字段
JavaScript模拟 - 爬虫优化
爬取速度:使用多线程,多进程等方法加速爬虫程序获取数据的速度。
异常处理:在数据获取时,可能存在因为网络问题、网址问题导致的程序异常,一个网址出现的异常即可中断整个程序,需要定义异常处理方法。 - 数据保存
数据清洗。
数据存储。
2.Python网络爬虫工具
2.1.urllib
2.1.1.urllib模块简介
urllib是Python中内置的HTTP请求库,提供了一系列用于操作URL的功能,其中包括URL发送请求、解析、对请求异常时的处理和对于robots文件的处理。
urllib在Python2和Python3中对应的版本是不同的:
- Python2中有urllib和urllib2两个模块,两个模块经常一起使用。
- Python3中urllib和urllib2合并为新的urllib模块。
2.1.2.urllib模块的组成
urllib主要分为四个模块:
- urllib.request:请求模块
- urllib.error:异常处理模块
- urllib.parse:url解析模块
- urllib.robotparser:robots.txt解析模块
2.1.3.urllib.request
urllib.request模块提供了基本URL(主要是HTTP,还包括FTP等协议)请求的方法,利用它可以模拟浏览器向目标主机发送请求的过程。
模块中封装了:
- basic and digest authentication(basic认证和digest认证)
- redirections(HTTP重定向)
- cookies(浏览器cookies)等处理方法
2.1.4.请求方法-urlopen
urlopen方法用于模拟浏览器向目标主机发送请求,例如:urlopen("www.huawei.com")
。但是urlopen并不能做到完全模拟浏览器。
urllib.request.urlopen(url,data=None,[timeout,]*,cafile=None,capath=None,cadefault=False,context=None):发送一个简单的请求。返回值为响应对象。
- url:访问的地址
- data:请求参数(不为None时,发送post请求)
- timeout:设置网站的访问超时时间。例如,
response=urllib.request.urlopen('https://www.huawei.com',timeout=5)
2.1.5.响应对象
响应对象(response)中包含了数据、状态码等响应信息:
- read():读取响应的对象的内容
- info():返回HTTPMessage对象,表示远程服务器返回的头信息
- getcode():返回http状态码。
response.read():获取请求内容(数据、网页HTML代码等信息,不同网站的编码格式不同,在打印时可能会出现乱码)
response.getcode():请求状态信息(200成功,300重定向,400客户端错误,500服务器错误)
2.1.6.请求方法-Request
在使用浏览器访问目标主机时,浏览器会自动带有一些信息如headers字段信息,这些信息是urlopen无法添加的,为了更好的伪装成浏览器,需要使用到Request方法。
- host:目标主机(请求服务器地址)
- cookies:身份信息
- Refer:跳转链接
- User-Agent:用户代理(浏览器信息,不添加则为Python版本信息)
urllib.request.Request(url,data=None,headers={},origin_req_host=None,unverifiable=False,method=None):构造一个请求类,用于向服务器发送。
- url:访问的地址。
- headers:http响应headers字段信息。
- origin_req_host:指的是请求方的host名称或者IP地址。
- method:用来指示请求使用的方法,比如GET,POST等。
2.1.7.urllib.error
在使用爬虫程序获取数据时,经常遇到一些错误:请求异常、网络中断等,这些错误产生时,urllib也提供了对应的处理措施,这些方法被封装在urllib.error模块中。
urllib.error中的异常类有两个:
- URLError:继承自OSError,是error异常模块的基类,由request模块产生的异常都可以通过它来处理。
- HTTPError:URLError的子类,用于处理HTTP请求错误。
- Code:返回HTTP状态码
- Reason:返回错误的原因
区别:
- URLError封装的错误信息一般是由网络引起的,包括url错误。
- HTTPError封装的错误信息一般是服务器返回了错误状态码。
关系:
- URLError是OSError的子类,HTTPError是URLError的子类。
2.1.8.error模块的使用
捕获异常
from urllib import request
from urllib import error
try:
response=request.Request('http://xxx.xxx')
except error.HTTPError as e_http:
print(e_http.reason)
except error.URLError as e_url:
print(e_url)
except Exception as e:
print('others')
2.1.9.urllib.parse
在urllib中提供了一个用于url操作的子模块-parse模块,其中封装了url的解析、合并、编码和解码等操作。
在发送请求时URL中通常包含了一些信息:例如,https://www.baidu.com/s?ie=UTF-8&wd=Python
链接中,协议是https,域名是www.baidu.com,查询字符串(get)是ie=UTF-8&wd=Python。
2.1.10.URL解析
parse模块中提供了用于解析URL的方法-urlparse:
urllib.parse.urlparse(url,scheme=’’,allow_fragments=True)
- url:待解析的url
- scheme:假如解析的url没有协议,可以设置默认的协议
- allow_fragments=True:是否忽略锚点。
import urllib.parse
url="https://www.baidu.com/s?ie=UTF-8&wd=Python"
result=urllib.parse.urlparse(url=url)
print(result)
解析结果:
ParseResult(scheme='https', netloc='www.baidu.com', path='/s', params='', query='ie=UTF-8&wd=Python', fragment='')
- scheme:协议
- netloc:域名
- path:路径
- params:参数
- query:查询字符串
- fragment:锚点
2.1.11.URL拼接
parse模块下提供了join方法用于将一个不完整的链接拼接为一个完整的链接(在提供基础链接的前提下)。
urllib.parse.urljoin(base,url,allow_fragment=True)
- base:基础链接
- url:不完整链接
import urllib.parse
base_url='https://www.baidu.com/s?ie=UTF-8&wd=Python'
sub_url='/info'
full_url=urllib.parse.urljoin(base_url,sub_url)
print(full_url)
# https://www.baidu.com/info
2.1.12.URL字符编码
urllib.parse.urlencode():将字典形式的数据,转化为url编码后的字符串。
import urllib.parse
parmas={
'wd':'中文',
'ky':'python123'
}
parmas_str=urllib.parse.urlencode(parmas)
print(parmas_str)
# wd=%E4%B8%AD%E6%96%87&ky=python123
urllib.parse.quote():对中文进行URL编码(unquote方法可以解码)
import urllib.parse
print(urllib.parse.quote('汉语'))
# %E6%B1%89%E8%AF%AD
2.1.13.urllib使用代理IP
urllib中使用代理IP有两种方式:
- 设置代理地址,创建Proxyhandler,创建Opener,安装Opener,使用请求方法访问。
- 设置代理地址,创建Proxyhandler,创建Opener,直接使用opener发送请求。
创建代理IP(可以使用多个代理IP创建代理IP池)
proxies={'http':'115.216.40.204:9999'}
创建代理IP对象
proxy=urllib.request.ProxyHandler(proxies)
创建opener对象
opener=urllib.request.build_opener(proxy)
使用IP有两种方式:
第一种方式
urllib.request.install_opener(opener)
urllib.request.urlopen('www.huawei.com')
第二种方式
opener.open('www.huawei.com')
2.2.Requests
2.2.1.Requests模块介绍
Requests:让HTTP服务人类。
Requests是基于urllib库,使用Python实现的简单易用的HTTP库,使用起来比urllib简洁很多。
Requests在Python2和Python3中通用,方法完全一样。
Requests安装:pip install requests。
2.2.2.Requests发送GET请求
requests.get(url,[headers,][proxies][params,]*args):模拟浏览器向目标主机发送get请求,返回response对象。
- url:服务器对应的地址。
- headers:HTTP请求中headers字段。
- proxies:设置代理IP地址。
- params:查询字符串。
2.2.3.GET请求参数使用
headers:字典格式,可以为请求添加headers字段。
headers={
"User-Agent":" ",
"Cookie":" ",
"Refer":" "
}
response=requests.get(url,headers=headers)
timeout:超时参数,用于设置请求时间,当超过时间仍未获得响应时,会抛出异常(可以结合retrying模块一起使用)。
response=requests.get(url,timeout=5)
verify:布尔类型,可以避免ssl证书安全问题。
params:查询字符串,即带有参数的请求。
kw={'kw':'python'}
response=requests.get(url,params=kw)
cookie:字典类型,用来接收请求时的cookie信息。
cookies={'cookie的name':'cookie的value'}
response=requests.get(url,cookies=cookies)
proxies:设置代理IP
proxies={
'http':'http://10.10.1.10:3128',
'https':'http://10.10.1.10:1080'
}
response=request.get(url,proxies=proxies)
2.2.4.Requests发送POST请求
requests.post(url,[data,][headers,][proxies,]*args):使用post方式向目标发送请求。
- url:服务器对应的地址。
- data:请求时携带的数据。
- headers:HTTP请求中headers字段。
- proxies:设置代理IP地址。
2.2.5.POST请求参数使用
data:请求时携带的表单数据,字典格式。
data={'kw':'python'}
response=requests.post(url,data=data)
2.2.6.响应对象
使用requests发送请求后会获取一个响应对象response。
响应信息:
- response.headers获取响应头信息。
- response.status_code获取响应状态码。
- response.encoding获取文本编码格式。
响应内容:
- response.text响应体str类。
- response.json()解码json数据。
响应内容(二进制):
- response.content获取二进制响应内容(推荐)。
原始响应内容:
- response.raw获取来自服务器的原始套接字响应(需要在请求时指定参数stream=True)。
其他:
- response.raise_for_status()响应码不为200时抛出异常。
2.2.7.Requests设置cookie信息
使用requests处理cookie有三种方法:
- 在headers字段中添加cookie字符串。
headers={‘cookie的name’:‘cookie的value’} - 把cookie字典传给请求方法的cookies参数接收。
cookies={‘cookie的name’:‘cookie的value’}
requests.get(url,headers=headers,cookies=cookie_dict) - 使用requests.session处理cookie。
2.2.8.requests.session
- 使用headers和cookie字典的方式设置cookie都需要手动去添加cookie信息,而requests.session不需要。
- requests提供了一个叫做session类,来实现客户端和服务端的会话保持。session实例在请求了一个网站后,对方服务器设置在本地的cookie会保存在session中,下一次再使用session请求对方服务器的时候,会带上前一次的cookie。
- 使用requests.session处理cookie:
session=requests.session()
response=session.get(url,headers)
2.2.9.Requests模块中常用异常
- 网络问题导致的异常:ConnectionError。
- HTTP返回失败的状态码:Response.raise_for_status()会抛出一个HTTPError异常。
- 请求超时:Timeout异常。
2.3.Selenium
2.3.1.Selenium简介
Selenium是一个Web的自动化测试工具,最初是为网站自动化测试而开发的,Selenium可以直接运行在浏览器上,支持所有主流的浏览器(包括PhantomJS这些无界面的浏览器),可以接收指令,让浏览器自动加载页面,获取需要的数据,甚至页面截屏。
- PhantomJS:是一个基于Webkit的无界面(headless)浏览器,它会把网站加载到内存并执行页面上的JavaScript。
- Chromedriver:也是一个能够被Selenium驱动的浏览器。
使用Selenium对于JavaScript渲染的数据和模拟登陆处理起来非常容易,缺点是效率相对低,因为通常要等到页面把所有数据加载完才开始工作(Selenium也提供了相关解决方案,具体参考Selenium文档)。
2.3.2.Selenium基本使用
使用Selenium进行简单的浏览器操作:
from selenium import webdriver
# 创建driver对象时可以根据机器上存在的浏览器创建
driver=webdriver.Edge() # 创建driver对象
driver.get('https://www.baidu.com') # 发送请求
driver.page_source # 查看数据
driver.close() # 退出当前页面
driver.quit() # 推出浏览器
2.3.3.Selenium的其他方法
实例化driver对象:driver=webdriver.浏览器类。
- Selenium处理cookie:driver.get_cookies()能够获取所有的cookie。
- driver.window_handles:获取浏览器所打开的所有窗口。
- driver.switch_to.window:根据窗口的编号进行窗口切换。
- driver.forward():前进。
- driver.back():后退。
- 点赞
- 收藏
- 关注作者
评论(0)