PythonCrawler 13day03

PythonCrawler 13day03

愉快的十一假期结束了,接下来就要快乐的学习起来啊啊啊!!!
爬虫系列进行到第三天。。。

1. ajax请求的抓取

动态加载页面信息的提取

当我们浏览一个新闻类的网站,例如微博,今日头条,知乎等,由于它的内容极多,当我们搜索某一关键词的信息后,服务器只会向我们返回少量的数据,微博和头条是返回指定数量的数据,当我们再次向下刷新的时候,会再次通过Ajax请求返回指定数目的数据(如果你的网络不好时,会出现一个表示正在加载的小圆圈的动画效果)。知乎是当浏览器的滚动条触底时,再次提取数据。这就产生了一个问题,通过爬虫如何来提取通过Ajax请求动态加载的数据呢?
模拟Ajax请求
这时需要通过Chrome等浏览器的开发者工具,利用Chrome开发者工具的筛选功能筛选出所有的Ajax请求。选择network选项,直接点击XHR分析网页后台向接口发送的Ajax请求,用requests来模拟Ajax请求,那么就可以成功抓取信息了。

简单的说Ajax就是一段js代码,通过这段代码,可以让页面发送异步的请求,或者向服务器发送一个东西,即和服务器进行交互

对于ajax:

  • 一定会有 url,请求方法(get, post),可能有数据
  • 有些网页内容使用Ajax加载,而Ajax一般返回的是JSON直接对Ajax地址进行post或get,就返回JSON数据了。
  • 一般使用 json 格式
request库的get请求代码
#coding=utf-8

import requests
url = ' https://movie.douban.com/j/chart/top_list?type=11&interval_id=100%3A90&action='
headers = {"User-Agent":"Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0"}
data = {
    "start":"20",
    "limit":"20",
    }
response = requests.get(url,params = data,headers = headers)
print response.text

输出结果为:
在这里插入图片描述

.request库的post请求
#coding=utf-8

import requests
url = ' https://movie.douban.com/j/chart/top_list?type=11&interval_id=100%3A90&action='
formdata = {
    "start":"20",
    "limit":"20"
    }
headers = {"User-Agent":"Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0"}
response = requests.post(url,data=formdata,headers=headers)
print response.text

输出结果为:
在这里插入图片描述
爬取豆瓣电影xiao实例
网站分析:

  • 打开豆瓣电影网站:https://movie.douban.com/,选择【排行榜】,点击【动作】分类
  • 一直往下滑,可以看到这样的效果:快到低的时候又有了新的内容,也就是往下没完
  • 基本可以判定使用了 ajax 请求,进行异步的加载
    在这里插入图片描述
    然后进去检查请求的信息:
  • 1.右键【检查】>【Network】或者直接点击F12
  • 2.向下滚动页面
  • 3.可以看到请求在不断不更新,点击一个请求,就可以看到请求的信息
    在这里插入图片描述
# 爬取豆瓣电影数据
# 了解ajax的爬取方式
# https://movie.douban.com/

from urllib import request
import json

# url信息:interval_id表示排名段(可自行修改),limit限制20个
url = "https://movie.douban.com/j/chart/top_list?type=5&interval_id=100%3A90&action=&start=20&limit=20"

rsp = request.urlopen(url)
data = rsp.read().decode()

data = json.loads(data)

# 遍历输出每个'k'和'v'的值
for item in data:
      print("排名:", item['rank'], "\n",
            "名称:", item['title'], "\n",
            "类型:", item['types'], "\n",
            "主演:", item['actors'], "\n",
            "分数:", item['score'],"\n-------------",)

输出结果如下:
在这里插入图片描述

2. HTTPS请求的使用

HTTP协议(HyperText Transfer Protocol,超文本传输协议):是一种发布和接收 HTML页面的方法。

HTTPS(Hypertext Transfer Protocol over Secure Socket Layer)简单讲是HTTP的安全版,在HTTP下加入SSL层。

SSL(Secure Sockets Layer 安全套接层)主要用于Web的安全传输协议,在传输层对网络连接进行加密,保障在Internet上数据传输的安全。
HTTP的请求与响应
HTTP通信由两部分组成: 客户端请求消息 与 服务器响应消息
在这里插入图片描述
浏览器发送HTTP请求的过程:

  • 当用户在浏览器的地址栏中输入一个URL并按回车键之后,浏览器会向HTTP服务器发送HTTP请求。HTTP请求主要分为“Get”和“Post”两种方法。
  • 当我们在浏览器输入URL http://www.baidu.com
    的时候,浏览器发送一个Request请求去获取http://www.baidu.com
    的html文件,服务器把Response文件对象发送回给浏览器。
  • 浏览器分析Response中的 HTML,发现其中引用了很多其他文件,比如Images文件,CSS文件,JS文件。
    浏览器会自动再次发送Request去获取图片,CSS文件,或者JS文件。
  • 当所有的文件都下载成功后,网页会根据HTML语法结构,完整的显示出来了。

现在随处可见https开头的网站,urllib可以为HTTPS请求验证SSL证书,就像web浏览器一样,如果网站的SSL证书是经过CA认证的,则能够正常访问,比如:添加链接描述
如果SSL证书验证不通过,或者操作系统不信任服务器的安全证书,比如浏览器在访问12306网站如:https://www.12306.cn/mormhweb/的时候,会警告用户证书不受信任。
一般会报着这样的错

(SSLError("bad handshake: Error([('SSL routines', 'tls_process_server_certificate', 'certificate verify failed')],)",),))

解决办法

import ssl
from urllib import request
#表示忽略未经核实的ssl正书认证
ssl._create_default_https_context = ssl._create_unverified_context
base_url = 'https://www.wbiao.cn'
response = request.urlopen(base_url)
print(response.read().decode('utf-8'))

小例子

from urllib import request
import ssl
#忽略验证证书
context = ssl._create_unverified_context
url = 'https://www.12306.cn/mormhweb/'
response = request.urlopen(url)
info = response.read().decode('utf-8')
print(info)

输出结果为:
在这里插入图片描述

3.设置代理proxy

加入一个网站它会检测某一段时间某个IP的访问次数,如果访问次数过多,它会禁止你的访问。所以你可以设置一些代理服务器来帮助你做工作,每隔一段时间换一个代理访问网站。
分类
透明代理:目标网站知道你使用了代理并且知道你的源IP地址,这种代理显然不符合我们这里使用代理的初衷

匿名代理:匿名程度比较低,也就是网站知道你使用了代理,但是并不知道你的源IP地址

高匿代理:这是最保险的方式,目标网站既不知道你使用的代理更不知道你的源IP

代码如下:

from urllib.request import ProxyHandler
from urllib.request import build_opener

proxy = ProxyHandler({"http": "119.109.197.195.80"})
opener = build_opener(proxy)
url = "http://www.baidu.com"
response = opener.open(url)
print(response.read().decode("utf-8"))

4.cookie的使用

Cookie,指某些网站为了辨别用户身份,进行Session跟踪而存储在用户本地终端上的数据(通常加密),就比如有些网站需要登录后才能访问某个页面,在登录之前,你想抓取某个页面内容是不允许的。那么我们可以利用Urllib库保存登录的Cookie,然后在抓取其他页面就达到目的了。

Cookie的引文原意是“点心”,它是在客户端访问Web服务器时,服务器在客户端硬盘上存放的信息,好像是服务器发送给客户的“点心”。服务器可以根据Cookie来跟踪客户状态,这对于需要区别客户的场合(如电子商务)特别有用。

当客户端首次请求访问服务器时,服务器先在客户端存放包含该客户的相关信息的Cookie,以后客户端每次请求访问服务器时,都会在HTTP请求数据中包含Cookie,服务器解析HTTP请求中的Cookie,就能由此获得关于客户的相关信息。
在这里插入图片描述
因此我们使用登录以后的Cookie。自己编辑Cookie访问Web服务器。网络爬虫中Cookie的两种使用方式,代码中网页已经不存在,但是可以自己在其他网页中尝试。我们使用的是登录之后的Cookie
1、直接将Cookie写在header头部,代码如下:

# coding:utf-8
import requests
from bs4 import BeautifulSoup
cookie = '''cisession=19dfd70a27ec0eecf1fe3fc2e48b7f91c7c83c60;CNZZDATA1000201968=181584
6425-1478580135-https%253A%252F%252Fwww.baidu.com%252F%7C1483922031;Hm_lvt_f805f7762a9a2
37a0deac37015e9f6d9=1482722012,1483926313;Hm_lpvt_f805f7762a9a237a0deac37015e9f6d9=14839
26368'''
header = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Geck
o) Chrome/53.0.2785.143 Safari/537.36',
'Connection': 'keep-alive',
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Cookie': cookie}
url = 'https://kankandou.com/book/view/22353.html'
wbdata = requests.get(url,headers=header).text
soup = BeautifulSoup(wbdata,'lxml')
print(soup)

2、使用requests插入Cookie,代码如下:

# coding:utf-8
import requests
from bs4 import BeautifulSoup
cookie = {
"cisession":"19dfd70a27ec0eecf1fe3fc2e48b7f91c7c83c60",
"CNZZDATA100020196":"1815846425-1478580135-https%253A%252F%252Fwww.baidu.com%252F%7C1483
922031",
"Hm_lvt_f805f7762a9a237a0deac37015e9f6d9":"1482722012,1483926313",
"Hm_lpvt_f805f7762a9a237a0deac37015e9f6d9":"1483926368"
}
url = 'https://kankandou.com/book/view/22353.html'
wbdata = requests.get(url,cookies=cookie).text
soup = BeautifulSoup(wbdata,'lxml')
print(soup)

这样我们就轻松的使用Cookie获取到了需要登录验证后才能浏览的网页和资源了。上面的Cookie是从自己浏览的网页中复制粘贴得到的。

5.URLError使用

首先解释下URLError可能产生的原因:

  • 网络无连接
  • 连接不到特定的服务器
  • 服务器不存在
    在代码中,我们需要用try-except语句来包围并捕获相应的异常,代码如下:
from urllib.request import Request, urlopen
from urllib.error import URLError

url = "http://www.sx435334t.cn/index/us3er.html"
try:
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36"
    }
    req = Request(url, headers=headers)

    resp = urlopen(url, timeout=1)

    print(resp.read().decode())
except URLError as e:
    if len(e.args) == 0:
        print(e.code)
    else:
        print(e.args[0])

print("获取数据完毕")

我们利用了 urlopen方法访问了一个不存在的网址,运行结果如下:

[Errno 11001] getaddrinfo failed
获取数据完毕

3.requests请求的使用

对了解一些爬虫的基本理念,掌握爬虫爬取的流程有所帮助。入门之后,我们就需要学习一些更加高级的内容和工具来方便我们的爬取。

第一步利用 pip 安装

pip install requests
  • 基本请求
req = requests.get("http://www.baidu.com")
req = requests.post("http://www.baidu.com")
req = requests.put("http://www.baidu.com")
req = requests.delete("http://www.baidu.com")
req = requests.head("http://www.baidu.com")
req = requests.options("http://www.baidu.com")

  • get请求
    参数是字典,我们也可以传递json类型的参数:
import requests

url = "http://www.baidu.com/s"
params = {'wd': '尚学堂'}
response = requests.get(url, params=params)
print(response.url)
response.encoding = 'utf-8'
html = response.text
# print(html)

  • post请求
    参数是字典,我们也可以传递json类型的参数:
url = "http://www.sxt.cn/index/login/login.html"
formdata = {
    "user": "17703181473",
    "password": "123456"
}
response = requests.post(url, data=formdata)
response.encoding = 'utf-8'
html = response.text
# print(html)

  • 自定义请求头部

伪装请求头部是采集时经常用的,我们可以用这个方法来隐藏:


headers = {'User-Agent': 'python'}
r = requests.get('http://www.zhidaow.com', headers = headers)
print(r.request.headers['User-Agent'])

- 设置超时时间

可以通过timeout属性设置超时时间,一旦超过这个时间还没获得响应内容,就会提示错误

requests.get('http://github.com', timeout=0.001)
  • 代理访问
    采集时为避免被封IP,经常会使用代理。requests也有相应的proxies属性
import requests

proxies = {
  "http": "http://10.10.1.10:3128",
  "https": "https://10.10.1.10:1080",
}

requests.get("http://www.zhidaow.com", proxies=proxies)

如果代理需要账户和密码,则需这样

proxies = {
    "http": "http://user:pass@10.10.1.10:3128/",
}

  • session自动保存cookies
    seesion的意思是保持一个会话,比如 登陆后继续操作(记录身份信息) 而requests是单次请求的请求,身份信息不会被记录
# 创建一个session对象 
s = requests.Session() 
# 用session对象发出get请求,设置cookies 
s.get('http://httpbin.org/cookies/set/sessioncookie/123456789') 
  • ssl验证
# 禁用安全请求警告
requests.packages.urllib3.disable_warnings()

resp = requests.get(url, verify=False, headers=headers)

获取响应信息

代码含义
resp.json()获取响应内容(以json字符串)
resp.text获取响应内容 (以字符串)
resp.content获取响应内容(以字节的方式)
resp.headers获取响应头内容
resp.url获取访问地址
resp.encoding获取网页编码
resp.request.headers请求头内容
resp.cookie获取cookie

代码全部在照哥的GIT
总结如上,加油啊

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值