爬虫请求

爬虫的分类

  • 通用爬虫通用爬虫是搜索引擎抓取系统(百度、谷歌、搜狗等)的重要组成部分。主要是将互联网上的网页下载到本地,形成一个互联网内容的镜像备份。

  • 聚焦爬虫(定向爬虫):是面向特定需求的一种网络爬虫程序,他与通用爬虫的区别在于:聚焦爬虫在实施网页抓取的时候会对内容进行筛选和处理,尽量保证只抓取与需求相关的网页信息。

HTTP协议

HTTP(Hyper Transfer Protocal)协议,中文名为超文本传输协议,是一种发布和接收HTML页面的方法。服务器端口号是80端口。

HTTPS协议,是HTTP协议的加密版本,在HTTP下加入了SSL层。服务器端口号是443端口。

HTTP请求过程

当浏览器向服务器发送HTTP请求时,它就会发送一个Request请求html文件,服务器就会把Response文件对象发送回浏览器。当浏览器在分析Response中的html,发现其中引用了很多如css的其他文件,那么浏览器就会自动地再次发送Response去获取其他文件。

URL详解

URL是Uniform Resource Locator的简称,称为统一资源定位符。

scheme://host:port/path/?query-string=xxx#anchor

  • scheme代表访问的协议,有httphttpsftp等。

  • host代表主机,域名。

  • post代表端口号,浏览器默认为80

  • path查找的路径。如https://www.zhihu.com/question/317729805/answer/634561449question/317729805/answer/634561449就是路径。

  • query-string查询字符串,如www.baidu.com/s?wd=python其中wd=python就是查询字符串。

  • anchor网页的锚点

请求头的常见参数

User-Agent浏览器的名称,通过爬虫请求的话默认是python。因此,如果我们想要正常获取信息的话,就需要把这个值设置成一些浏览器的值。

Referer表面当前这个请求时从哪个URL发送过来的,如果不是指定的页面,那么就不做任何响应。

Cookie``HTTP协议是无状态的,因此需要用Cookie来做标识。如果想要访问登陆后才能访问的网站,那么就需要发送Cookie信息。

urllib

urllib库可以模拟浏览器的行为,向指定的服务器发送一个请求,并可以保持服务器返回的数据。所有和网络请求相关的方法,都被搜集到了urllib.request模块下了。

urlopen函数

from urllib import request
resp = request.urlopen("https://www.cnblogs.com")
print((resp.read()).decode("utf-8"))

该函数向URL发送请求,然后返回一个叫http.client.HTTPResponse的类文件句柄的对象。其有readreadlinereadlinesgetcode等方法。

urlretrieve

该函数与urlopen函数类似,不过它可以把文件下载下来。

from urllib import request
request.urlretrieve("https://www.cnblogs.com","blog.html")

urlencode函数

当浏览器向服务器发送请求时,会自动的把中文或者其他特殊字符进行编码。如果我们用代码来发送请求就需要用urlencode函数来进行编码,它可以把字典数据转换成URL编码的数据。

from urllib import parse
data = {
    "name":"袁铭",
    "hometown":"眉山"
}
qs = parse.urlencode(data)
print(qs)
"""
name=%E8%A2%81%E9%93%AD&hometown=%E7%9C%89%E5%B1%B1
"""

parse_qs函数

利用parse_qs函数可以对url参数进行解码。

from urllib import parse
qs = "name=%E8%A2%81%E9%93%AD&hometown=%E7%9C%89%E5%B1%B1"
data = parse.parse_qs(qs)
print(data)
'''
{'name': ['袁铭'], 'hometown': ['眉山']}
'''

urlparseurlsplit函数

urlparse函数和urlsplit函数可以对url中的各个部分进行分割。其中urlparse会生成一个SplitResult对象,而urlparse会生成一个ParseResult对象,且比SplitResult多一个params属性。

##urlparse()函数
from urllib import request,parse
url = "https://baijiahao.baidu.com/s?id=1629848884406903523&wfr=spider&for=pc"

res = parse.urlparse(url)
print(res)
"""
result:
ParseResult(scheme='https', netloc='baijiahao.baidu.com', path='/s', params='', query='id=1629848884406903523&wfr=spider&for=pc', fragment='')
"""
##urlsplit()函数
from urllib import request,parse
url = "https://baijiahao.baidu.com/s?id=1629848884406903523&wfr=spider&for=pc"
res = parse.urlsplit(url)
print(res)
"""
result:
SplitResult(scheme='https', netloc='baijiahao.baidu.com', path='/s', query='id=1629848884406903523&wfr=spider&for=pc', fragment='')
"""

params属性

params属性用的比较少,url = 'http://www.baidu.com/s;hello?wd=python&username=abc#1'中,hello就是params属性。比如:

from urllib import request,parse
url = 'http://www.baidu.com/s;hello?wd=python&username=abc#1'
res = parse.urlparse(url)
print(res.params)
"""
result:
hello
"""

request.Request

request.Request类里面可以添加一些请求头。

from urllib import request
headers = {
    "User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36"
}
resp = request.Request("https://baijiahao.baidu.com/s?id=1629848884406903523&wfr=spider&for=pc",headers=headers)
res = request.urlopen(resp)
print(res.read().decode("utf-8"))

ProxyHandler处理器(代理设置)

通过这个设置可以防止因为一个IP地址多次访问一个网站而被禁止访问的现象。

from urllib import request
handler = request.ProxyHandler({"http":"116.209.56.20"})
opener = request.build_opener(handler)
req = request.Request("https://httpbin.org/ip")
res = opener.open(req)
print(res.read())

Cookie及其在python爬虫中应用

http请求是无状态的,即第一次和服务器连接登陆后,第二次依然需要登陆,这样我们就需要Cookie了。Cookie 是指网站服务器为了辨别用户身份和进行Session跟踪,而储存在用户浏览器上的文本文件,Cookie可以保持登录信息到用户下次与服务器的会话。一般的浏览器只会存储4kb大小的Cookie信息。

Cookie格式

Set-Cookie: NAME=VALUE;Expires/Max-age=DATE;Path=PATH;Domain=DOMAIN_NAME;SECURE
  • NAME:Cookie的名字

  • VALUE:Cookie的值

  • Expires:Cookie的过期时间

  • Path:Cookie的作用路径

  • Domain:Cookie作用的域名

  • SECURE:是否只在https协议下起作用

HTTPCookieProcessor模拟登陆

自己把相关Cookie信息复制下来的方法

from urllib import request
header = {
    "User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36",
    "Cookie":'''_zap=7e00df33-291a-444c-bbd5-a577341759a3; d_c0="AJAneIGlfA6PTmd1grAygRROsv0NXxdm5CY=|1541663054"; _xsrf=0drRAYeKwmdbZ11UYOF8cJy9ZRT1cMec; z_c0="2|1:0|10:1543657267|4:z_c0|92:Mi4xSHFOUEJnQUFBQUFBa0NkNGdhVjhEaVlBQUFCZ0FsVk5NNlh2WEFBckU4ZE5mUjRPdHdzTFpiMS1uXzRHTUFRdWVn|b16b34b217ea382b1094e15ca41eac496c65ae276e30a492b77ab06b4824561d"; __gads=ID=72e38c174d9d49c9:T=1547028103:S=ALNI_Maqfn0xeXVKXQ3l2ty6KhIGzTq6wg; tst=r; __utma=51854390.323199518.1550992135.1550992135.1550992135.1; __utmz=51854390.1550992135.1.1.utmcsr=zhihu.com|utmccn=(referral)|utmcmd=referral|utmcct=/; __utmv=51854390.100--|2=registration_date=20171026=1^3=entry_date=20171026=1; q_c1=69c989b9edc24cc991722eaef9f39ec0|1552728574000|1541663056000'''
}
resq = request.Request("https://www.zhihu.com/",headers=header)
res = request.urlopen(resq)
with open("pachong.html","wb") as f:
    f.write(res.read())

模拟登陆与http.cookiejar模块

该模块具有以下的几个类:

  • CookieJar:管理、存储和向外传输HTTP Cookie
  • FileCookieJar(filename,delayload=None,policy=None):该模块是从CookieJar派生来的,可以创建FileCookieJar实例,并把相关信息存储到文件里。
    • filename:存储Cookie的文件名
    • delayload:该属性为True时,支持延迟访问文件
  • MozillaCookieJar(filename,delayload=None,policy=None):该模块从FileCookieJar派生而来,创建与Mozilla浏览器cookies.txt兼容的FileCookieJar实例
  • LWPCookieJar(filename,delayload=None,policy=None):也是从FileCookieJar派生而来,创建与libwww-perl标准的Set-Cookie3文件格式兼容的FileCookieJar实例

小实例

from urllib import parse,request
from http.cookiejar import CookieJar
headers = {
    "User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36"
}
cookiejar = CookieJar()
handle = request.HTTPCookieProcessor(cookiejar)
opener = request.build_opener(handle)
data = {
    "username":"***********",  
    "password":"***********" 
}  ##存储登陆账号和密码,对应的参数可以在html源代码中查找
data = parse.urlencode(data).encode("utf-8")
login_url = "https://www.zhihu.com/signup?next=%2F" ##使用登陆页面的url
req = request.Request(login_url,headers=headers,data=data)  
opener.open(req) ##登陆并获得Cookie
url = "https://www.zhihu.com/question/60371302/answer/632445421"
req = request.Request(url,headers=headers)
resp = opener.open(req)
with open("zhihu.html","wb") as f:
    f.write(resp.read())

Cookie本地化和本地加载

from urllib import request
from http.cookiejar import MozillaCookieJar

cookiejar = MozillaCookieJar("cookie.txt")
handler = request.HTTPCookieProcessor(cookiejar)
opener = request.build_opener(handler)

headers = {
   'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36'
}
req = request.Request('http://httpbin.org/cookies',headers=headers)

resp = opener.open(req)
print(resp.read())
cookiejar.save(ignore_discard=True,ignore_expires=True)##如果断开Cookie就消失的话,就应该设置`save()`函数里面的参数
from urllib import request
from http.cookiejar import MozillaCookieJar

cookiejar = MozillaCookieJar("cookie.txt")
cookiejar.load(ignore_expires=True,ignore_discard=True) ##加载
handler = request.HTTPCookieProcessor(cookiejar)
opener = request.build_opener(handler)

headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) >AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 >Safari/537.36'}
req = request.Request('http://httpbin.org/cookies',headers=headers)

resp = opener.open(req)
print(resp.read())

requests

get及其实例化的属性

  • params:接受一个字典或者字符串的查询参数,其不需要urlencode()就可以转换成url编码,如requests.get("https://www.baidu.com/s",kw,headers=heads),其中kw={"wd":"python},它会自动地把url拼接为https://www.baidu.com/s?wd=pyhon
  • text:返回Unicode格式的内容
  • content:返回字节流数据,其会自动帮你解码,但是容易出错
  • url:返回其完整的url地址
  • encoding:查看响应头部字符编码
  • status_code:查看响应码

小实例

import requests
kw = {
    "wd":"python"
}
headers = {
    "User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36"
}
resp = requests.get("http://www.baidu.com/s",params = kw,headers=headers)
with open("res.html","w",encoding="utf-8") as f:
    f.write(resp.content.decode("utf-8"))

post及其小实例

import requests

url = "https://www.lagou.com/jobs/positionAjax.json?city=%E6%B7%B1%E5%9C%B3&needAddtionalResult=false&isSchoolJob=0"

headers = {
   'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36',
   'Referer': 'https://www.lagou.com/jobs/list_python?labelWords=&fromSearch=true&suginput='
}

data = {
   'first': 'true',
   'pn': 1,
   'kd': 'python'
}

resp = requests.post(url,headers=headers,data=data)
# 如果是json数据,直接可以调用json方法
print(resp.json())

使用代理

import requests
url = "http://httpbin.org/ip"
headers = {
    "User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36"
}
proxy = {
    "http":"182.34.37.198:9999"
}
resp = requests.get(url,headers=headers,proxies=proxy) ##直接传入get()函数里面
print(resp)

Cookie的获取

import requests
url = "https://www.zhihu.com/signup?next=%2F"
data = {
    "username":"15244847273",
    "password":"GNIM@yuan#88"
}
headers = {
    "User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36"
}
resp = requests.get(url)
c_s = resp.cookies  ##调用cookie这个属性来获得cookie值
print(c_s.get_dict()) ##get_dict()函数会把产生的对象返回成字典的形式

Session

利用该类可以建立一个会话

import requests
url = "https://www.zhihu.com/signup?next=%2F"
data = {
    "username":"***********",
    "password":"***********"
}
headers = {
    "User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36"
}
session = requests.Session()
session.post(url,data=data,headers=headers)
reps = session.get("https://www.zhihu.com/question/317115184/answer/631075262")
print(reps.text)

不被信任的SSL证书处理

resp = requests.get("URL",verify=False)

get()函数里面加入verify=False参数就可以处理了

posted @ 2019-04-06 09:33  Mingle_Yuan  阅读(268)  评论(0编辑  收藏  举报