Urllib代理和模拟登录

自定义Opener

我们之前一直都在使用的urlopen,它是一个特殊的opener,是模块帮我们创建好的。但是我们可以不用他的,我们可以重新写一个

自定义Opener会有更高级的用法

import urllib.request
# 构建一个HTTPHandler 处理器对象,支持处理HTTP请求
http_handler = urllib.request.HTTPHandler()
# 构建一个HTTPHandler 处理器对象,支持处理HTTPS请求
# http_handler = urllib.request.HTTPSHandler()
# 调用urllib.request.build_opener()方法,创建支持处理HTTP请求的opener对象
opener = urllib.request.build_opener(http_handler)
# 构建 Request请求
request = urllib.request.Request("http://www.baidu.com/")
# 调用自定义opener对象的open()方法,发送request请求
response = opener.open(request)
# 获取服务器响应内容
print (response.read().decode())

代理设置

在这里插入图片描述

    • 代理的作用:

      • 1.突破自身IP访问限制,访问一些平时不能访问的站点。

      • 2.访问一些单位或团体内部资源:比如使用教育网内地址段免费代理服务器,就可以用于对教育网开放的各类FTP下载上传,以及各类资料查询共享等服务。

      • 3.提高访问速度:通常代理服务器都设置一个较大的硬盘缓冲区,当有外界的信息通过时,同时也将其保存到缓冲区中,当其他用户再访问相同的信息时,则直接由缓冲区中取出信息,传给用户,以提高访问速度。

      • 4.隐藏真实IP:上网者也可以通过这种方法隐藏自己的IP,免受攻击。对于爬虫来说,我们用代理就是为了隐藏自身IP,防止自身的IP被封锁。

    • 根据协议划分

      • FTP代理服务器**:主要用于访问FTP服务器,一般有上传、下载的功能以及缓存的功能,端口号一般为21,2121等。**

      • HTTP代理服务器**:主要用于访问网页,一般有内容过滤和缓存的功能,端口号一般为80、8080、3128等**

      • SSL/TLS代理:主要能用于访问加密的网站,一般有SSL或者TLS加密**

      • SOCKS代理:只是单纯的用于传输数据包,不关心具体的协议用法,速度快、有缓存功能,端口号一般为1080

    • 根据匿名内容划分

      • 高度匿名代理:会将数据包原封不动的转发,在服务器看来就好像真的是一个普通的用户短在访问,而记录的IP就是代理服务器的IP

      • 普通匿名代理:会在数据包上做一些改动,服务端上有可能发现这个是代理服务器,也有一定的几率追查到客户端的真实IP.

      • 透明代理:不但改动了数据包,还会告诉服务器客户端的真实IP,这种代理除了用缓存技术提高浏览器速度。能用内容过滤提高安全性之外,并没有其他作用。

      • 使用代理IP这是爬虫/反爬虫的第二大招,通常也是最好用的。

  • 代理网站

    • 西刺免费代理IP
    • 快代理免费代理
from urllib import request,error
#构建支持代理的handler
proxy = {
    'http':'61.138.33.20:808',
    'https':'120.69.82.110:44693',
}
proxy_handler = request.ProxyHandler(
    proxies=proxy
)
#付费代理的话 
#构建一个私密代理Handler,需要加上私密代理账户的用户名和密码
# authproxy = {
#    "http" :"username:password@61.135.217.7:80"
#}
# authproxy_handler=urllib.request.ProxyHandler(
#    proxies=authproxy
#)
#根据proxy_handler实例化一个opener对象
opener = request.build_opener(proxy_handler)
url = 'http://www.baidu.com/'
# 使用https://httpbin.org/get接口验证使用了代理
# url = 'https://httpbin.org/get'
try:
    response = opener.open(url,timeout=5)
    print(response.status)
except error.HTTPError as err:
    print(err.reason)
except error.URLError as err:
    print(err.reason)
# 1. 如果按照上面代码,只有使用opener.open()方法发送
请求才使用自定义的代理,而urlopen()则不使用自定义代理。
response = opener.open(request)
# 2. 将自定义的opener设置为全局的opener,之后所有的,不管是
opener.open()还是urlopen() 发送请求,都将使用自定义代理。
# request.install_opener(opener)
# response = urlopen(request)

案例

西刺爬爬爬

这个用的json保存的数据,(列表转json用dumps),
import urllib.request
import re
import ssl
import json

ssl._create_default_https_context = ssl._create_unverified_context


class XiCiSpied():
    def __init__(self):
        self.url = 'https://www.xicidaili.com/nn/'
        self.headers = {
            'User_Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36',
        }
        self.proxy_list = []

    def send_request(self,url):
        request = urllib.request.Request(headers=self.headers,url=url)
        response = urllib.request.urlopen(request)
        if response.status == 200:
            return response

    def save_content(self):
        #用json去保存
        with open('proxy.json','wa') as f:
            #wa为了防止后面的内容覆盖到前面的
            f.write(json.dumps(self.proxy_list))#把列表转json
            




    def parse_content(self,response):
        content = response.read().decode('utf8')
        pattern = re.compile(r'<td>(\d.*?\.\d.*?\.\d.*>\.\d.*?)</td>.*?<td>(\d.*?)</td>.*?<td>(^HT.*?)</td>',re.S)
        result = re.findall(pattern,content)
        #print(result)

        for proxy in result:
            #proxy是元组
            file_proxy = {}
            file_proxy['type'] = proxy[2]
            file_proxy['proxy'] = proxy[0] + ':'+proxy[1]
            self.proxy_list.append(file_proxy)
            #类型应该是
            #[{'type':.'...','proxy':'.....'},{},{}....]






    def strat(self):
        for i in range(1,3):
            full_url = self.url + str(i)
            response = self.send_request(full_url)
            if response:
                self.parse_content(response)
            self.save_content()



if __name__ == '__main__':
    xc = XiCiSpied()
    xc.strat()

西刺已经爬下来了,但是用的时候应该怎么用呢(json转列表用loads)

import urllib.request
import re
import ssl
import json
import random

ssl._create_default_https_context = ssl._create_unverified_context


class XiCiSpied():
    def __init__(self):
        self.url = 'https://www.xicidaili.com/nn/'
        self.headers = {
            'User_Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36',
        }
        #先从文件中把数据读出来
        f = open('proxy.json','r')
        #self.proxy_list = f.read()#这个返回的是json字符串,我们为了方便,把json再转化为列表
        self.proxy_list = json.loads(f.read())#用列表展示出来


    def send_request(self, url):
        #每次发送请求都换一个ip
        proxy = random.choice(self.proxy_list)#每次随机选择列表里的一个字典
        #取出来的数据就是{'',''}
        #拼一个代理请求
        proxy_user = {
            proxy['type']:proxy['proxy']
            #http        :域名+端口
            #取出来的形式就是这种
        }
        #构造好了代理,就可以发送请求了
        #第一步创建一个代理的处理器,ProxyHandler
        ProxyHandler = urllib.request.ProxyHandler(
            proxies=proxy_user
        )
        #第二步,根据proxyhandler实例化一个opener对象
        opener = urllib.request.build_opener(ProxyHandler)
        #然后就可以创建request,发送请求了
        request = urllib.request.Request(headers=self.headers, url=url)
        response = opener.open(request)#用我自己写的代理去爬
        if response.status == 200:
            return response

    def save_content(self):
        # 用json去保存
        with open('proxy.json', 'wa') as f:
            # wa为了防止后面的内容覆盖到前面的
            f.write(json.dumps(self.proxy_list))  # 把列表转json


    def strat(self):
        for i in range(1, 3):
            full_url = self.url + str(i)
            response = self.send_request(full_url)
            print(response.read().decode('utf8'))#把爬下来的数据转为pycharm中的语言
            self.save_content()


if __name__ == '__main__':
    xc = XiCiSpied()
    xc.strat()

urllib模拟登录

找cookie,它的作用,最直接的一个就是检测用户是否登录


from urllib.request import urlopen, Request

url = 'https://www.douban.com/people/215936188/'
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36',
           'Cookie':'ll="118109"; bid=MBXAroZsxpg; __gads=ID=807be06ae84daac4:T=1586955001:S=ALNI_MbNx5wdtDXSr1YcYP6kc0Hzrm-lEQ; douban-fav-remind=1; __yadk_uid=m6SxzsoQjJAgI1dKZbMAafkN1UB9e3i1; push_noty_num=0; push_doumail_num=0; __utmv=30149280.21593; douban-profile-remind=1; gr_user_id=e29cb43e-c8cd-406c-8cfa-0f9f40721306; _vwo_uuid_v2=DA157A200A3523F60609A6064D6D6AC7E|f4c9a8fcb2b43a2a794ccbbddbf6c0e6; ct=y; __utmc=30149280; viewed="35026481_35013916_34787187_34429244_5907931"; _pk_ref.100001.8cb4=%5B%22%22%2C%22%22%2C1592043440%2C%22https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3DenlCus0VTvqF-g0PNsBGwVH7QXvKHuaoW9A8DGTyzAgp6LIRXKks4G2DBDFgjnfJ%26wd%3D%26eqid%3D9b37fe5600100819000000045ee4a7ad%22%5D; _pk_ses.100001.8cb4=*; __utma=30149280.1178102369.1587959982.1592021478.1592043442.12; __utmz=30149280.1592043442.12.11.utmcsr=baidu|utmccn=(organic)|utmcmd=organic; __utmt=1; dbcl2="215936188:WVVGPPVRVy4"; ck=eEss; ap_v=0,6.0; _pk_id.100001.8cb4=3c5cdcff0213d411.1587105741.12.1592043607.1592022425.; __utmb=30149280.5.10.1592043442',
           }
ret = Request(url, headers=headers)
res = urlopen(ret)
with open('douban.html','wb') as f:
    f.write(res.read())

但是遇到这种的,每次都去登录然后获取cookie有点麻烦

模拟登录,不用去登录再去复制cookie了



from urllib.request import urlopen, Request
from http.cookiejar import CookieJar
import urllib.parse

login_url = 'https://www.wanandroid.com/user/login'
form_data = {
    'username':'liuand',
    'password':'l200011280028..',
}
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36',
           }
form_data = urllib.parse.urlencode(form_data).encode('utf8')#编码

cookiejar = CookieJar()
 #创建一个处理cookie 的 handler
httpcookieProcessor = urllib.request.HTTPCookieProcessor(cookiejar)
#通过build_opener()来构建opener
opener = urllib.request.build_opener(httpcookieProcessor)
#创建一个request
request = Request(login_url, headers=headers)
#发起请求
response = opener.open(request,data=form_data)
# with open('douban.html','wb') as f:
#     f.write(response.read())
print(response.read().decode('utf8'))
#然后爬收藏页
url = 'https://www.wanandroid.com/lg/collect'
response = opener.open(url)
with open('wanandroid.html','wb') as f:
    f.write(response.read())
print(response.read)

模拟登录的核心代码and详细解释

import http.cookiejar as cookiejar
from urllib import parse,request
#1.构造一个CookieJar对象实例来保存cookie
cookie = cookiejar.CookieJar()
# 2.使用HTTPCookieProcessor()创建cookie处理器对象,
# 参数为CookieJar()对象
cookie_handler = request.HTTPCookieProcessor(cookie)
#3.通过build_opener()来构建opener
opener = request.build_opener(cookie_handler)
#4.addheaders接受一个列表,里面每一个元素都是一个headers信息的元组
#opener将会附带header信息
opener.addheaders = [
    ('User-Agent','Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:59.0) Gecko/20100101 Firefox/59.0'),
]
#5.需要登录账号和密码
data = {
    'source': 'index_nav',
    'form_email': '18518753265',
    'form_password': 'ljh123456',
}
#6. 通过urlencode()转码
postdata = parse.urlencode(data).encode('utf-8')
#7. 构建Request请求对象,包含需要发送的用户名和密码
request = request.Request("https://www.douban.com/accounts/login", data = postdata)
# 8. 通过opener发送这个请求,并获取登录后的Cookie值,
opener.open(request)
# 9. opener包含用户登录后的Cookie值,可以直接访问那些登录后才可以访问的页面
response = opener.open("https://www.douban.com/people/175417123/")
#这里为了测试不添加cookie时访问改界面的效果
#headers = {
#    'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:59.0) Gecko/20100101 #Firefox/59.0',
#}
# request = request.Request('https://www.douban.com/people/175417123/',headers=headers)
# response = request.urlopen(request)
# 10. 打印响应内容
#打印结果查看是否访问成功
print(response.code)
html = response.read().decode('utf-8')
# print(html)
with open('douban_login.html','w') as f:
    f.write(html)

药智网案例

from http.cookiejar import CookieJar
import urllib.request
import re
import ssl
import json
import urllib.parse

ssl._create_default_https_context = ssl._create_unverified_context

class YZSpider():
    def __init__(self):
        self.login_url = 'https://www.yaozh.com/login/'
        self.member_url = 'https://www.yaozh.com/member/'
        self.headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36',
            }
        self.cookiejar = CookieJar()
        #然后再创建一个处理cookie的handler
        self.cookie_handler = urllib.request.HTTPCookieProcessor(self.cookiejar)
        # 通过build_opener()来构建opener
        self.opener = urllib.request.build_opener(self.cookie_handler)
        #所有的data这些参数都是需要用urlencode编码的
        self.form_data = urllib.parse.urlencode({
            'username':'liuand',
            'pwd':'l200011280028..',
            'formhash': 'B790FFD297',
            'backurl': 'https % 3A % 2F % 2Fwww.yaozh.com % 2F'
        }).encode('utf8')


    def send_request(self):
        request = urllib.request.Request(headers=self.headers,data=self.form_data,url=self.login_url)
        response = self.opener.open(request)
        if response.status == 200:
            print('已经登录了')
            request = urllib.request.Request(self.member_url,headers=self.headers,data=self.form_data)
            response = self.opener.open(request)
            if response.status == 200:
                print('获取会员页成功')
                self.save_content(response)


    def save_content(self,reponse):
        with open('yaozhi.html','wb') as f:
            f.write(reponse.read())



    def paser_content(self):
        pass

if __name__ == '__main__':
    yz = YZSpider()
    yz.send_request()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值