zoukankan      html  css  js  c++  java
  • 随便记录下写爬虫遇到的问题

    记录编写爬虫中遇到的一些坑

    1. 或许会持续更新(咕咕咕)
    2. 遇到的问题会分类总结

    使用的Python库

    • requests:用于最基本的发送HTTP请求,包括get请求和post请求
    • bs4:将获得的HTTP响应体进行格式化组织,从而能够进行多种检索
    • re:对检索到的标签更细化地提取信息
    • ThreadPoolExecutor, ProcessPoolExecutor:多线程与多进程,提高爬取速度
    • 其他库:os、time等等,用于其他各种非主要用途

    反爬虫绕过

    请求头

    • 一些网站会检测HTTP请求头里的信息,从而判断是否是爬虫访问。此时需要对请求头进行伪装。
      • 使用浏览器自带的F12,查看每一次HTTP连接的请求头,复制到代码里并将其手动转换成字典形式的header
      • 在使用requests发送请求时,带上参数headers=,r=requests.get(url, headers=header);header必须是dict,这样可以在请求时带上给定的请求头

    cookies

    • 使用F12或者一些拦截工具burp等手动查看cookies,在使用requests发送请求时,带上参数cookies=

    请求速度

    • 过快的请求速度(明显超过一般浏览速度的请求)可能会被网站监测并被ban掉ip或是限制访问
      • 使用time.sleep(random.randint(a,b))来暂停一个随机时间
      • 使用IP代理,在requests请求时,带上参数proxies=proxy,proxy应该是一个dict,形式为{'ip':'port'},可以有多个IP代理
      • 使用IP代理,在requests请求时,带上参数proxies=proxy,proxy应该是一个dict,形式为{'http':'ip:port', 'https':'ip:port'},分别为使用HTTP代理和HTTPs代理。

    字符编码问题

    HTTP响应体的编码

    • 自动化解决方案:
    import requests
    r = requests.get(url)
    r.encoding = r.apparent_encoding
    

    这种方法自动猜测可能的编码方式,并用这种编码方式编码响应体。但是猜测会存在一定的错误,自动选择编码方式会无法编码某些特殊的字符,比如简体中文、繁体中文

    • 手动选择编码方式:
      在请求到的html文件首部,一般会有对本文件编码方式的声明,例如<meta http-equiv='Content-Type' content='text/html; charset=gbk'>里的charset字符集为gbk。此时,r.encoding='gbk'就可以选择gbk编码

    读写文件的编码

    • Python文件默认的是unicode编码,有时候会出现unicode字符集无法编码一些特定字符,报unicode错误
      • open()时,带上encoding=参数,指定编码方式encoding='utf-8',即可解决

    网络问题

    HTTPS验证

    • 一些使用HTTPS的网站在访问时,需要进行HTTPS验证,可以在requests请求时指定verify='pathofCAbundle'参数来使用本地证书验证,也可以简单指定为verify=False不进行验证
    • 关掉验证后urllib3会报一个warning,使用urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)关掉这个警告

    网络延迟重试

    • 使用requests.DEFAULT_RETRIES = 10来修改requests库默认的重试次数,在网络状况不佳或是对方服务器性能不高导致请求失败时使用

    流式文件下载

    • 在requests请求时带上stream=True,实现流式下载,在请求大文件时使用

    并发问题

    简单使用ThreadPoolExecutor即可解决。

    from future import ThreadPoolExecutor
    with ThreadPoolExecutor(max_workers=int) as pool:  # 声明了一个线程池
        pool.map(func, 可迭代数据结构如list)
    

    需要考虑对临界区资源进行加锁,可以使用l=threading.lock()来声明一个锁,l.acquire()来加锁,l.release()来解锁

  • 相关阅读:
    小程序(四):模板
    小程序(三):授权登录
    小程序(二)
    小程序(一)
    从零开始学习微信小程序
    flex 弹性布局
    如何使用docker进行shadsocks环境开发配置
    eclipse 设置注释模板
    idea 2019.1.3最新注册码
    centos7安装rabbitmq简单方式
  • 原文地址:https://www.cnblogs.com/unknown404/p/14243958.html
Copyright © 2011-2022 走看看