爬虫-第三篇-代理,cookie,验证码,线程池

news/2024/7/4 10:05:59

图片懒加载

有些图片网站img标签用了伪src属性,在页面加载时不会一次性加载所有图片,获取图片链接时,要注意img标签的属性,如下图,属性被修改为src2

1627982-20190828191731791-289658380.png

代理

在短时间内向网站发起了一个高频的请求,会产生ConectionPool的Error,连接池(http)中的资源被耗尽,可以在请求头中设置Connection:close,或者用代理ip进行访问.

  • 代理
    • 代理服务器:实现请求转发,从而可以实现更换请求的ip地址
    • 在requests中如何将请求的ip进行更换
  • 代理的匿名度:
    • 透明:服务器知道你使用了代理并且知道你的真实ip
    • 匿名:服务器知道你使用了代理,但是不知道你的真实ip
    • 高匿:服务器不知道你使用了代理,更不知道你的真实ip
  • 代理的类型:
    • http:该类型的代理只可以转发http协议的请求
    • https:只可以转发https协议的请求
  • 免费代理ip的网站
    • 快代理
    • 西祠代理
    • goubanjia
    • 代理精灵(推荐):http://http.zhiliandaili.cn/
  • 在爬虫中遇到ip被禁掉如何处理?
    • 使用代理
    • 构建一个代理池
    • 拨号服务器

示例:查看代理ip

import requests
headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36'
}

url = 'https://www.baidu.com/s?wd=ip'
# 开启代理:在请求中加入proxies={'http/https':'ip:port'}
page_text = requests.get(url=url,headers=headers,proxies={'https':'1.197.203.187:9999'}).text
with open('ip.html','w',encoding='utf-8') as fp:
    fp.write(page_text)

示例:构建代理ip池

#基于代理精灵构建一个ip池
from lxml import etree
import requests,os
headers={
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36'
}
all_ips = [] #列表形式的代理池
proxy_url = 'http://t.11jsq.com/index.php/api/entry?method=proxyServer.generate_api_url&packid=1&fa=0&fetch_key=&groupid=0&qty=52&time=1&pro=&city=&port=1&format=html&ss=5&css=&dt=1&specialTxt=3&specialJson=&usertype=2'
proxy_page_text = requests.get(url=proxy_url,headers=headers).text
tree = etree.HTML(proxy_page_text)
proxy_list = tree.xpath('//body//text()')
for ip in proxy_list:
    dic = {'https':ip}
    all_ips.append(dic)
print(all_ips)

示例:用上述线程池爬取西祠代理ip

#爬取西祠代理中的免费代理ip
url = 'https://www.xicidaili.com/nn/%d'
free_proxies = []
for page in range(1,30):
    new_url = format(url%page)
    page_text = requests.get(new_url,headers=headers,proxies=random.choice(all_ips)).text
    tree = etree.HTML(page_text)
    tr_list = tree.xpath('//*[@id="ip_list"]//tr')[1:]#xpath表达式中不可以出现tbody
    for tr in tr_list:
        ip = tr.xpath('./td[2]/text()')[0]
        port = tr.xpath('./td[3]/text()')[0]
        t_type = tr.xpath('./td[7]/text()')[0]
        
        dic = {
            'ip':ip,
            'port':port,
            'type':t_type
        }
        free_proxies.append(dic)
    print('第{}页爬取完毕!!!'.format(page))
print(len(free_proxies))
  • 作用:保存客户端的相关状态

  • 在请求中携带cookie,在爬虫中如果遇到了cookie的反爬如何处理?
    • 手动处理
      • 在抓包工具中捕获cookie,将其封装在headers中
      • 应用场景:cookie没有有效时长且不是动态变化
    • 自动处理
      • 使用session机制
      • 使用场景:动态变化的cookie
      • session对象:该对象和requests模块用法几乎一致.如果在请求的过程中产生了cookie,如果该请求使用session发起的,则cookie会被自动存储到session中.

示例:爬取雪球网中的新闻资讯数据:https://xueqiu.com/

#获取一个session对象
session = requests.Session()
main_url = 'https://xueqiu.com' #推测对该url发起请求会产生cookie
session.get(main_url,headers=headers)

url = 'https://xueqiu.com/v4/statuses/public_timeline_by_category.json'
params = {
    'since_id': '-1',
    'max_id': '20346152',
    'count': '15',
    'category': '-1',
}
page_text = session.get(url,headers=headers,params=params).json()
page_text

验证码识别

  • 相关的线上打码平台识别

    • 打码兔

    • 云打码

    • 超级鹰:

      http://www.chaojiying.com/about.html

      • 1.注册,登录(用户中心的身份认证)
      • 2.登录后:
        • 创建一个软件:软件ID->生成一个软件id
        • 下载示例代码:开发文档->python->下载

示例:将古诗文网中的验证码图片进行识别

import requests
from hashlib import md5

class Chaojiying_Client(object):

    def __init__(self, username, password, soft_id):
        self.username = username
        password =  password.encode('utf8')
        self.password = md5(password).hexdigest()
        self.soft_id = soft_id
        self.base_params = {
            'user': self.username,
            'pass2': self.password,
            'softid': self.soft_id,
        }
        self.headers = {
            'Connection': 'Keep-Alive',
            'User-Agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)',
        }

    def PostPic(self, im, codetype):
        """
        im: 图片字节
        codetype: 题目类型 参考 http://www.chaojiying.com/price.html
        """
        params = {
            'codetype': codetype,
        }
        params.update(self.base_params)
        files = {'userfile': ('ccc.jpg', im)}
        r = requests.post('http://upload.chaojiying.net/Upload/Processing.php', data=params, files=files, headers=self.headers)
        return r.json()

    def ReportError(self, im_id):
        """
        im_id:报错题目的图片ID
        """
        params = {
            'id': im_id,
        }
        params.update(self.base_params)
        r = requests.post('http://upload.chaojiying.net/Upload/ReportError.php', data=params, headers=self.headers)
        return r.json()

    
def getCodeImgText(imgPath,img_type):
    chaojiying = Chaojiying_Client('bobo328410948', 'bobo328410948', '899370')  #用户中心>>软件ID 生成一个替换 96001
    im = open(imgPath, 'rb').read()                                                 #本地图片文件路径 来替换 a.jpg 有时WIN系统须要//
    return chaojiying.PostPic(im, img_type)['pic_str']

#使用session捕获cookie,cookie来自验证码图片链接加载
s = requests.Session()
first_url = 'https://so.gushiwen.org/user/login.aspx?from=http://so.gushiwen.org/user/collect.aspx'
s.get(first_url,headers=headers)

url = 'https://so.gushiwen.org/user/login.aspx?from=http://so.gushiwen.org/user/collect.aspx'
page_text = requests.get(url,headers=headers).text
tree = etree.HTML(page_text)
img_src = 'https://so.gushiwen.org'+tree.xpath('//*[@id="imgCode"]/@src')[0]
img_code_data = s.get(img_src,headers=headers).content
with open('./gushiwen.jpg','wb') as fp:
    fp.write(img_code_data)
img_text = getCodeImgText('./gushiwen.jpg',1004)
print(img_text)

#动态捕获动态的请求参数
__VIEWSTATE = tree.xpath('//*[@id="__VIEWSTATE"]/@value')[0]
__VIEWSTATEGENERATOR = tree.xpath('//*[@id="__VIEWSTATEGENERATOR"]/@value')[0]

#点击登录按钮后发起请求的url:通过抓包工具捕获
login_url = 'https://so.gushiwen.org/user/login.aspx?from=http%3a%2f%2fso.gushiwen.org%2fuser%2fcollect.aspx'
data = {
    '__VIEWSTATE': __VIEWSTATE,
    '__VIEWSTATEGENERATOR': __VIEWSTATEGENERATOR,
    'from': 'http://so.gushiwen.org/user/collect.aspx',
    'email': 'www.zhangbowudi@qq.com',
    'pwd': 'bobo328410948',
    'code': img_text,
    'denglu': '登录',
}
main_page_text = s.post(login_url,headers=headers,data=data).text
with open('main.html','w',encoding='utf-8') as fp:
    fp.write(main_page_text)
  • 为什么在爬虫中需要实现模拟登录?
    • 有的数据是必须经过登录后才可以显示出来的!
  • 涉及到的反爬:
    • 验证码
    • 动态请求参数:每次请求对应的请求参数都是动态变化
      • 动态捕获:通常情况下,动态的请求参数都会被隐藏在前台页面的源码中
    • cookie

基于线程池的异步爬取

import requests
from multiprocessing.dummy import Pool
headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36'
}

url = 'https://www.qiushibaike.com/text/page/%d/'
urls = []
for page in range(1,11):
    new_url = format(url%page)
    urls.append(new_url)

def get_request(url): #必须有一个参数
    return requests.get(url,headers=headers).text

pool = Pool(10)
response_text_list = pool.map(get_request,urls) #使用自定义的函数func异步的处理urls列表中的每一个列表元素
print(response_text_list)

转载于:https://www.cnblogs.com/yinhaiping/p/11425943.html


http://www.niftyadmin.cn/n/3458661.html

相关文章

使用ApiPost模拟发送get、post、delete、put等http请求

现在的模拟发送请求插件很多比如老外的postman等,但亲测咱们国内的 ApiPost 更好用一些,因为它不仅可以模拟发送get、post、delete、put请求,还可以导出文档,支持团队协作也是它的特色。 另外老外的思维跟我们还是有些鸿沟&#x…

爬虫-第五篇-scrapy框架初识,持久化存储,手动请求发送

准备工作 什么是框架?如何学习框架? 就是一个集成了各种功能且具有很强通用性(可以被应用在各种不同的需求中)的一个项目模板.scrapy集成了哪些功能: 高性能的数据解析操作,持久化存储操作,高性能的数据下载的操作.....环境的安装: a. pip3 install wheelb. 下载twisted http…

出来混迟早要还的,技术债Dagger2:Android篇(上)

前言 因为工作需求,所以最近补了补之前没了解过的Dagger2的内容,基础篇已经发布。接下来就是Dagger2在Android中的应用了。当然,和我一样刚接触Dagger2的朋友,可以先看一下之前的基础文章: 出来混迟早要还的&#xff0…

JVM学习笔记之认识JDK(一)

1. HotSpot VM: HotSpot VM是Sun JDK和OpenJDK中所带的虚拟机,也是目前使用范围最广的Java虚拟机。 什么是HotSpot VM & 深入理解Java虚拟机 JVM? 提起HotSpot VM,相信所有Java程序员都知道,它是Sun JDK和OpenJDK中所带的虚拟…

JVM学习笔记之JDK、JRE、JVM的关系(二)

JDK(Java Development Kit)是针对Java开发员的产品,是整个Java的核心,包括了Java运行环境JRE、Java工具和Java基础类库。Java Runtime Environment(JRE)是运行JAVA程序所必须的环境的集合,包含J…

开发函数计算的正确姿势——运行 Selenium Java

2019独角兽企业重金招聘Python工程师标准>>> 前言 首先介绍下在本文出现的几个比较重要的概念: 函数计算(Function Compute): 函数计算是一个事件驱动的服务,通过函数计算,用户无需管理服务器等运行情况&am…

JVM学习笔记之初识JVM(三)

一、JVM在计算机中的位置 JVM调用操作系统,操作系统调用硬件,硬件反馈信息至操作系统,操作系统反馈信息至JVM 二、JVM的体系结构 JVM在执行过程中对内存的管理分为5个区域: 1.PC寄存器 2.Java虚拟机栈(JVM Stack) 3.本地方法栈(Na…

【转】协同开发中SVN使用规范试用

转自:http://www.cnblogs.com/BraveCheng/archive/2012/07/02/2573617.html 协同开发中SVN使用规范试用 目标,要求 本次svn提交规范主要针对当前项目中出现的svn管理难,开发流程控制难掌控,项目进度记录不准确等问题而提出。要求每…