随便记录下写爬虫遇到的问题

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

  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='\path\of\CAbundle'参数来使用本地证书验证,也可以简单指定为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()来解锁

posted @ 2021-01-06 22:53  柏凝  阅读(234)  评论(2编辑  收藏  举报