爬虫的深入了解

一 浏览网页是所要经历的过程

  1. 浏览器 (请求request)-> 输入URL地址(http://www.baidu.com/index.html file:///mnt ftp://172.25.254.250/pub …)

  2. http协议确定, www.baidu.com访问的域名确定 -> DNS服务器解析到IP地址

  3. 确定要访问的网页内容 -> 将获取到的页面内容返回给浏览器(响应过程)

二 爬取网页

  1. 基本方法:
    使用 urllib.request 中的 urlopen 去爬取
from  urllib import  request

respose = request.urlopen('http://www.baidu.com')
content = respose.read().decode('utf-8')
print(content)

执行结果:
在这里插入图片描述

  1. 使用Resuest对象(可以添加其他的头部信息)
from  urllib import  request

url = 'http://www.cbrc.gov.cn/chinese/jrjg/index.html'
headers = {'User-Agent':' Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Firefox/45.0'}

# 实例化request对象, 可以自定义请求的头部信息;
req = request.Request(url, headers=headers)
# urlopen不仅可以传递url地址, 也可以传递request对象;
content = request.urlopen(req).read().decode('utf-8')
print(content)

执行结果:
在这里插入图片描述

# 也可以后续添加信息
from  urllib import  request

url = 'http://www.cbrc.gov.cn/chinese/jrjg/index.html'
user_agent = 'Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Firefox/45.0'

# 实例化request对象, 可以自定义请求的头部信息;
req = request.Request(url)
req.add_header('User-Agent',user_agent)
# urlopen不仅可以传递url地址, 也可以传递request对象;
content = request.urlopen(req).read().decode('utf-8')
print(content)

执行结果:
在这里插入图片描述

  1. 反爬虫策略
    1). 伪装浏览器
    前面提到过,如果一些网站做了反爬虫策略,是禁止脚本进行访问的,但是浏览器却是可以的,因此这里要做的就是伪装成浏览器进行访问
    那么,先来看看浏览器是如何进行访问的
    在这里插入图片描述
    可以看到 liunx 系统在访问的时候的信息,其中有一项很重要的就是 User-Agent ,表明了访问时的身份
    下面是一些浏览器在访问时的信息:
 1.Android
    Mozilla/5.0 (Linux; Android 4.1.1; Nexus 7 Build/JRO03D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Safari/535.19
    Mozilla/5.0 (Linux; U; Android 4.0.4; en-gb; GT-I9300 Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30
    Mozilla/5.0 (Linux; U; Android 2.2; en-gb; GT-P1000 Build/FROYO) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1
 2.Firefox

    Mozilla/5.0 (Windows NT 6.2; WOW64; rv:21.0) Gecko/20100101 Firefox/21.0
    Mozilla/5.0 (Android; Mobile; rv:14.0) Gecko/14.0 Firefox/14.0
 3.Google Chrome

    Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.94 Safari/537.36
    Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19
 4.iOS
    Mozilla/5.0 (iPad; CPU OS 5_0 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9A334 Safari/7534.48.3

2). 代理IP
当抓取网站时, 程序的运行速度很快, 如果通过爬虫去访问, 一个固定的ip访问频率很高,网站如果做反爬虫策略, 那么就会封掉ip
(1)如何解决此问题呢?
1> 可以设置延迟

time.sleep(random.randint(1,5))

但是这样就违背了爬虫的原则
2> 就是使用代理IP
让其它的IP代替你去访问
(2)如何获取代理IP呢?
这里推荐一个西刺代理(http://www.xicidaili.com/),当然百度搜索也是可以的
(3)如何实现步骤?
1> 调用urllib.request.ProxyHandler(proxies=None); — 类似理解为Request对象
2> 调用Opener— 类似与urlopen, 这个是定制的
3> 安装Opener
4> 代理IP的选择

from  urllib import  request

url = 'https://www.whatismyip.com/'
# url = 'https://httpbin.org/get'
proxy = {'https':'171.221.239.11:808', 'http':'218.14.115.211:3128'}
user_agent = 'Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Firefox/45.0'
# 1).调用urllib.request.ProxyHandler(proxies=None);  --- 类似理解为Request对象
proxy_support = request.ProxyHandler(proxy)
# 2).调用Opener - -- 类似与urlopen, 这个是定制的
opener = request.build_opener(proxy_support)
# 伪装浏览器
opener.addheaders = [('User-Agent',user_agent)]
# 3).安装Opener
request.install_opener(opener)
# 4).代理IP的选择
response = request.urlopen(url)
content  = response.read().decode('utf-8')
print(content)

执行结果:
在这里插入图片描述
上面可以看到访问的网页为:(https://www.whatismyip.com/)
之所以选择这个,是因为这个网页正如其名那样,可以直接看到你的访问IP是多少
在这里插入图片描述
可以看到正是代理IP

三 cookie信息

  1. cookie信息是什么
    cookie:某些网站为了辨别用户身份, 只有登陆之后才能访问某个页面;
    进行一个会话跟踪, 将用户的相关信息包括用户名等保存到本地终端
    比如:CSDN在登陆后就保存有cookie信息
    在这里插入图片描述
    具体的内容:
BAIDUID=16C759B4BFCD1D2F65C8144247B56307:FG=1; 
BIDUPSID=16C759B4BFCD1D2F65C8144247B56307; 
PSTM=1531714425; 
MCITY=-233%3A; 
BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; 
pgv_pvi=2556628992; delPer=0; 
H_PS_PSSID=22778_1446_21105_18560_26350_20927; 
PSINO=1; pgv_si=s9417027584
  1. 如何查看cookie信息
from urllib.request import HTTPCookieProcessor
from urllib import request
from http import cookiejar
# 如何读取cookie信息
# 1). 声明一个CookieJar
cookie=cookiejar.CookieJar()
# 2). 利用urllib.request里面的HTTPCookieProcessor创建一个cookie处理器
handler=HTTPCookieProcessor(cookie)
# 3). 通过CookieHandler创建opener
opener=request.build_opener(handler)
# 4). 打开url页面
response=opener.open('https://www.csdn.net/')
# response=opener.open('https://www.baidu.com/')
# 5). 打印该页面的cookie信息
print(cookie)
for item in cookie:
    print(item)

执行结果:
在这里插入图片描述

  1. 如何将cookie保存到文件中
# 如何将cookie保存到文件中
# 1). 设置保存cookie的文件名
cookiefilename='cookie.txt'
# 2). 声明一个MozillaCookie,用来保存cookie信息并写入
cookie=cookiejar.MozillaCookieJar()
# 3). 利用urllib.request里面的HTTPCookieProcessor创建一个cookie处理器
handler=HTTPCookieProcessor(cookie)
# 4). 通过CookieHandler创建opener
opener=request.build_opener(handler)
# 5). 打开url页面
response=opener.open('https://www.csdn.net/')
# response=opener.open('https://www.baidu.com/')
# 6). 打印该页面的cookie信息
print(cookie)
cookie.save(cookiefilename,ignore_discard=True,ignore_expires=True)

执行结果:
在这里插入图片描述
文件中的具体内容:

# Netscape HTTP Cookie File
# http://curl.haxx.se/rfc/cookie_spec.html
# This is a generated file!  Do not edit.

.csdn.net	TRUE	/	FALSE	1735689600	dc_session_id	10_1539760133007.977319
.csdn.net	TRUE	/	FALSE	1855120121	uuid_tt_dd	5423497709313904182_20181017

  1. 如何从文件中读取cookie,并访问
# 如何从文件中读取cookie,并访问
# 1). 指定cookie文件地址
cookiefilename='cookie.txt'
 # 2). 声明一个MozillaCookie,用来读取cookie信息
cookie=cookiejar.MozillaCookieJar()
# 3).  读取cookie信息
cookie.load(filename=cookiefilename)
# 4). 利用urllib.request里面的HTTPCookieProcessor创建一个cookie处理器
handler=HTTPCookieProcessor(cookie)
# 5). 通过CookieHandler创建opener
opener=request.build_opener(handler)
# 6). 打开url页面
response=opener.open('https://www.csdn.net/')
# 7). 打印信息
print(response.read().decode('utf-8'))

执行结果:
在这里插入图片描述
这样就可以在下次访问的时候直接通过读取cookie信息进行访问

四 urllib常见异常处理
常见的异常:(URLError、HTTPError、ContentTooShortError…)
如果这时不确定是否会爬取成功时,不妨先用 try 作异常处理

from urllib import  request, error

try:
    url = 'https://www.baidu.com/hello.html'
    response = request.urlopen(url)
    print(response.read().decode('utf-8'))
except error.HTTPError as e:
    print(e.reason, e.code, e.headers, sep='\n')
except error.URLError as e:
    print(e.reason)
else:
    print("成功")

执行结果:
在这里插入图片描述

超时异常处理:

from urllib import request, error
import  socket
#
try:
    url = 'https://www.baidu.com'
    response = request.urlopen(url, timeout=0.01)
    print(response.read().decode('utf-8'))
except error.HTTPError as e:
    print(e.reason, e.code, e.headers, sep='\n')
except error.URLError as e:
    print(e.reason)
    if isinstance(e.reason, socket.timeout):
        print("超时")
else:
    print("成功")

执行结果:
在这里插入图片描述

五 url解析

  1. 在 urllib.parse 中有一个 urlparse 可以将url进行分解
    网址的解析:
from urllib.parse import urlparse
url='http://www.google.com/search?hl=en&q=urlparse&btnG=Google+Search'
parse_info=urlparse(url)
print(parse_info)
print(parse_info.netloc)
print(parse_info.path)

执行结果:
在这里插入图片描述

  1. 在 urllib.parse 中同样有一个 urlencode 可以将url进行组合
    网址的组合:
from urllib.parse import urlencode
params={
    'name':'westos',
    'age':20
}
base_url='https://www.baidu.com'
url=base_url + urlencode(params)
print(url)

执行结果:
在这里插入图片描述

  1. 应用
    要求:
    获取网页的协议与网址,并按一定要求构成新的网址
from urllib.parse import urlparse, urlencode

url1='https://movie.douban.com/subject/4864908/comments?start=20&limit=20&sort=new_score&status=P'
parse_news=urlparse(url1)
print(parse_news.scheme)
print(parse_news.netloc)

params2={
    'start':20,
    'limit':20,
    'sort':'new_score',
    'status':'P'
}
base_url2='https://movie.douban.com/subject/4864908/comments'
url2=base_url2 + urlencode(params2)
print(url2)

执行结果:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_42668123/article/details/83111224