爬虫初识

本文介绍了爬虫的基本概念,包括使用requests和BeautifulSoup等工具进行网页抓取,并探讨了网站反爬策略,如通过请求信息、登录验证、验证码、用户行为等识别爬虫。同时,文章讨论了应对反爬的策略,如调整爬虫速度、使用UA池、IP池和Cookie池,以及自动化处理加密参数和验证码的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

爬虫

博客参考

  1. 开源模块:
  • requests
    response = requests.get(“url”)
    response.text
    response.content
    response.encoding = response.apparent_encoding # 使用网站编码
    response.status_code
    response.cookies.get_dict()
    requests.get(“url”, cookie={‘xx’: ‘yy’})
    requests.request方法参数:
    -method: 提交方式
    -url: 提交URL
    -params: 在URL中传递的参数
requests.request(
	method='GET',
	url='http://www.baidu.com',
	params={'k1':'v1','k2':'v2'}
)

-data: 在请求体重传递的参数

requests.request(
	method='GET',
	url='http://www.baidu.com',
	data={'k1':'v1','k2':'v2'}
)

-json: 在请求体重传递的参数(字典中嵌套字典时使用)

requests.request(
	method='GET',
	url='http://www.baidu.com',
	data={'k1':'v1','k2':{'k3':'v3'}}
)

-headers: 请求头

requests.request(
	method='POST',
	url='https://github.com/login',
	data={'k1':'v1','k2':{'k3':'v3'}},
	headers={
		'Referer': 'https://github.com/',
		'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36'
	}
)

-cookies: Cookies
-session: 用于保存客户端历史访问信息

import requests
def requests_session():
    session = requests.Session()

    ### 1、首先登陆任何页面,获取cookie
    i1 = session.get(url="http://dig.chouti.com/help/service")

    ### 2、用户登陆,携带上一次的cookie,后台对cookie中的 gpsd 进行授权
    i2 = session.post(
        url="http://dig.chouti.com/login",
        data={
            'phone': "8615131255089",
            'password': "xxxxxx",
            'oneMonth': ""
        }
    )

    i3 = session.post(
        url="http://dig.chouti.com/link/vote?linksId=8589623",
    )
    print(i3.text)
  • beautisoup
    安装:pip install requests beautifulsoup4

饭粒1:爬取汽车之家新闻页

import requests
from bs4 import BeautifulSoup

url = 'https://www.autohome.com.cn/all/'
response = requests.get(url)
response.encoding = response.apparent_encoding   # 使用网站编码
soup = BeautifulSoup(response.text, features='html.parser')
content = soup.find(id='auto-channel-lazyload-article')
# 组合条件:soup.find('div', class='c1')
li_list = content.find_all('li')   # 返回列表
for i in li_list:
    a = i.find('a')
    if a:
        # 新闻URL
        url = a.attrs.get('href').strip('//')
        print(url)
        # 新闻标题
        text = a.find('h3').text   # 获取标签内容
        print(text)
        # 新闻图片URL
        img_url = 'http://' + a.find('img').attrs.get('src').strip('//')
        # 保存图片
        img_response = requests.get(url=img_url)
        file_name = 'image' + os.path.sep + str(uuid.uuid4()) + '.jpg'
        with open(file_name, 'wb') as f:
            f.write(img_response.content)

饭粒2:登陆github

import requests
from bs4 import BeautifulSoup

# 获取token
r1 = requests.get('https://github.com/login')
s1 = BeautifulSoup(r1.text, 'html.parser')
token = s1.find(name='input', attrs={'name': 'authenticity_token'}).get('value')
r1_cookie_dict = r1.cookies.get_dict()

# 将用户名密码token发送到服务端,post
"""
github登陆默认post提交的信息:
utf8:✓
authenticity_token:ollV+avLm6Fh3ZevegPO7gOH7xUzEBL0NWdA1aOQ1IO3YQspjOHbfnaXJOtVLQ95BtW9GZlaCIYd5M6v7FGUKg==
login:asdf
password:asdf
commit:Sign in
"""
r2 = requests.post(
    'https://github.com/session',
    data={
        "utf8": '✓',
        "authenticity_token": token,
        'login': 'afengbo',
        'password': 'woshimima',
        'commit': 'Sign in'
    },
    cookies=r1_cookie_dict
)
r2_cookie_dict = r2.cookies.get_dict()
cookie_dict = {}
cookie_dict.update(r1_cookie_dict)
cookie_dict.update(r2_cookie_dict)

# 获取个人信息页面
r3 = requests.get(
    url='https://github.com/settings/emails',
    cookies=cookie_dict
)
print(r3.text)

网站反爬策略

为啥要反爬

出于保护自身网站有价值的数据资源、保护自身网站服务器资源的目的,识别出爬虫程序,限制恶意访问请求。

网站如何识别爬虫

爬虫程序和一般的人类使用的如浏览器、app等对于网站服务端来说,都是客户端程序。`网站反爬本质上是需要先找出真正人类用户和爬虫程序的区别`。
  1. 通过请求信息识别
    • Headers
      UA
      Referer
    • Cookie
      登录
      验证码
    • 特定请求参数
      是否具备且是正确token、sign等加密参数
  2. 基于用户行为识别
    • 单位时间的单个客户端的请求频率
      IP
      UA
      账号(cookie)
      三者组合
    • 鼠标移动轨迹
      是否有鼠标移动事件
      鼠标移动是否符合人类行为特征(如先加速后减速特征)
    • 键盘输入事件
  3. 频繁/定期更换反爬措施
  • 网站如何惩治爬虫
    网站一旦识别出某个请求是爬虫,通常会采取以下措施:
  1. 直接拒绝爬虫请求
    4xx
    2xx + 空数据
  2. 返回验证码验证,验证不通过,则拒绝访问或再次返回验证
  3. 不拒绝爬虫,但返回比较真实的伪数据和真数据混在一起

要实现网站的反反爬,必须先分析出网站的反爬策略到底是怎样的,然后才能对症下药。

  1. 确定自己被反爬
  2. 找出原因如何被反爬的

对于反爬策略常年不变的,那么只需要写几个简单的测试爬虫,就能找到网站的反爬策略。但如果是频繁更新反爬策略的网站,那么你就需要定期检测网站反爬策略,或利用爬虫程序监控,一旦爬虫获取不到正确的数据时,发出警报,然后立刻检查,看网站反爬策略是否发生变化,因为通常都是这个导致的爬虫运行一段时间后,出现无法正确获取数据的情况。


网站反爬策略应对

通常网站来说,其反爬措施如果过于严厉,则可能出现误判,如误将正常的用户请求封杀了,这样势必会影响网站的用户体验。
因此网站限制的不是爬虫的所有访问,而是主要限制短时间内发起的批量性爬虫请求。如果爬虫程序如同正常人一样访问网站,一般情况下,网站即使识别出你是爬虫,但出于对用户体验的考虑,而选择不处理你。
应对反爬策略基本方案,也就是别让自己的爬虫程序太肆无忌惮,这样可能让网站即使识别出你而不反爬你:

  • 能慢下来的就不要太快
  • 破解困难较大的,适当的牺牲一点自动化(如登录时手动打码)

当想要进一步提高程序的自动化和采集效率时,那么必须要根据网站的反爬策略来制定相应的应对策略:
也就是说,我们的反反爬其实就是解决两个问题:

  1. 采集效率问题
    UA池+IP池+Cookie池模拟多个客户端发起请求
  2. 程序完全自动化运行问题
    爬虫程序自动生成加密参数
    爬虫程序自动化处理验证码

UA池、IP池、Cookie池

  • UA池
    UA池是最好解决的,一般使用时不用考虑更新。可自行收集一些ua,或者使用fake-useragent等模块

  • IP池
    IP池相对复杂一点,使用时需要考虑定期更新,且需要不断检测IP的质量情况

  • 代理池维护架构:
    在这里插入图片描述

    • 获取器:定期从代理IP来源处获取IP,如代理IP商、免费代理。实现参考:利用reqeusts等定义将获取代理IP
    • 过滤器:对代理IP进行入库检测,初步过滤不可用代理IP。实现参考:利用tornado.httpclient或aiohttp等(因为自身是异步的),通过访问百度首页等,逐一过滤判断代理IP的可用性
    • 代理队列:将过滤的可用代理IP存储起来,由于是分布式,因此可考虑将代理IP放入redis中存储。实现参考:利用Redis的有序集合类型存储代理IP,默认权重可设为100
    • 定时检测器:由于IP一定时间后可能会失效,因此需要定期检测代理队列中所有的IP的可用性。
    • 实现参考:定期遍历Redis有序集合中的代理IP,使用过滤器中的同样方法检测,一旦发现有不可用代理IP,则将权重降低,当降低到一次分值时,如90、80等,则可删除该IP。
  • 代理IP来源:

  1. 免费代理:质量普遍较差,不推荐
  2. 代理IP提供商(如蘑菇代理讯代理):属于常用方式
  3. 代理隧道服务(如阿布云的HTTP隧道,推荐使用):其原理是,请求交由固定的阿布云转发,它内部维护着一个庞大的IP池,由它随机或指定一个IP进行转发。优点是不用自己维护代理池,代理速度与稳定性都不错,缺点是IP无法自己筛选和维护。
  4. ADSL拨号代理:原理是购买一批ADSL VPS服务器来,通过不断的拨号和重拨号,获得批量的IP,对应服务商有云立方青果云无极网络等。优点是IP独享使用,速度特别快、稳定性也极强,缺点是成本高昂,实现相对比较复杂。
    ADSL拨号代理实现原理:

在这里插入图片描述
Cookie池(主要指记录有登录状态的Cookie)
当网站登录接口比较复杂(如需要处理验证码),或如果在代码中频繁登录可能导致的账号被限制等情况,同时又需要使用多用户解决反爬问题时,那么就需要使用到Cookie池

Cookie池的维护,但主要是还考虑以下几个问题:

  • Cookie获取:手动登录后,存储Cookie,注意池中每个用户只有一个Cookie,也就是有多少个用户,就可以考虑建立多大的池
  • Cookie的更新:根据网站设定Cookie的过期时间,定期更新Cookie
自动生成加密参数

网站请求参数中部分参数是通过加密后发出的,对于PC web端,该加密参数都是通过JS代码生成的,其自动化实现思路都是通过分析网站前端JS代码,找到对应加密算法/函数,然后利用js2py/pyexecjs等技术实现在python中自动化生成加密参数。

举栗:百度翻译
在这里插入图片描述
利用搜索定位与chrome的断点调试找到对应的sign值生成函数
在这里插入图片描述

  • 验证码处理方案
  1. 简单验证码:直接利用OCR识别,tessersor模块
  2. 滑动验证码、点触类型验证码:计算坐标
  3. 手机验证码、网银U盾等:无解,无法实现自动化

现在很多滑动、点触验证码都是使用的极验验证码,对于这类验证码如果考虑破解参数、还原图片等方式处理,是非常耗时耗力的,而且不同网站的结构不一,无法做到统一。

如果是滑动,那么就利用缺口图和原图进行像素比对,找到缺口位置的坐标,利用selenium进行拟人化的拖拽;

对于如点触、混淆的文字识别都是考虑利用第三方打码平台(如超级鹰),进行识别获取坐标等。因为它们有非常强大的素材库,识别度高。然后利用seleinum来模拟鼠标点击行为实现,但要注意的是鼠标轨迹的人类特征模拟。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值