[华为云在线课程][Python网络爬虫][爬虫实现流程和工具][二][学习笔记]

举报
John2021 发表于 2022/05/31 22:45:29 2022/05/31
【摘要】 1.爬虫实现流程 1.1.爬虫常用的工具HTTP请求工具库:http.client,urllib,requests。爬虫框架:Scrapy,Scrapy-Redis,PySpider。其他工具:Selenium,chromediriver。 1.2.爬虫工作的流程URL:统一资源定位符,网址。爬虫的工作过程大概可以总结为:发送请求->获取相应->提取数据。 1.3.爬虫程序的实现步骤确定U...

1.爬虫实现流程

1.1.爬虫常用的工具

HTTP请求工具库:http.client,urllib,requests。
爬虫框架:Scrapy,Scrapy-Redis,PySpider。
其他工具:Selenium,chromediriver。

1.2.爬虫工作的流程

URL:统一资源定位符,网址。
爬虫的工作过程大概可以总结为:发送请求->获取相应->提取数据。

1.3.爬虫程序的实现步骤

  1. 确定URL
    网址范围确定,因为网页中存在很多其他网页的链接,这些链接中有一部分并不是当前网站内的链接,或者并不是我们获取数据所需的链接。
  2. 网页分析
    网页分析:动态网页还是静态页面。
    URL分析:在获取数据时,存在翻页的操作,翻页后的URL往往存在着规律。动态加载数据的网页可以通过直接查找数据对应的URL即可。
    数据分析:通过网页源代码查看数据的位置,定位数据后使用工具获取。
  3. 工具选取
    Requests,urllib等HTTP请求工具。
    Scrapy,PySpider框架。
  4. 反爬
    代理IP
    Headers字段
    JavaScript模拟
  5. 爬虫优化
    爬取速度:使用多线程,多进程等方法加速爬虫程序获取数据的速度。
    异常处理:在数据获取时,可能存在因为网络问题、网址问题导致的程序异常,一个网址出现的异常即可中断整个程序,需要定义异常处理方法。
  6. 数据保存
    数据清洗。
    数据存储。

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有三种方法:

  1. 在headers字段中添加cookie字符串。
    headers={‘cookie的name’:‘cookie的value’}
  2. 把cookie字典传给请求方法的cookies参数接收。
    cookies={‘cookie的name’:‘cookie的value’}
    requests.get(url,headers=headers,cookies=cookie_dict)
  3. 使用requests.session处理cookie。

2.2.8.requests.session

  1. 使用headers和cookie字典的方式设置cookie都需要手动去添加cookie信息,而requests.session不需要。
  2. requests提供了一个叫做session类,来实现客户端和服务端的会话保持。session实例在请求了一个网站后,对方服务器设置在本地的cookie会保存在session中,下一次再使用session请求对方服务器的时候,会带上前一次的cookie。
  3. 使用requests.session处理cookie:
session=requests.session()
response=session.get(url,headers)

2.2.9.Requests模块中常用异常

  1. 网络问题导致的异常:ConnectionError。
  2. HTTP返回失败的状态码:Response.raise_for_status()会抛出一个HTTPError异常。
  3. 请求超时: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():后退。
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。