python爬虫构建代理ip池抓取数据库的示例代码


Posted in Python onSeptember 22, 2020

爬虫的小伙伴,肯定经常遇到ip被封的情况,而现在网络上的代理ip免费的已经很难找了,那么现在就用python的requests库从爬取代理ip,创建一个ip代理池,以备使用。

本代码包括ip的爬取,检测是否可用,可用保存,通过函数get_proxies可以获得ip,如:{'HTTPS': '106.12.7.54:8118'}

下面放上源代码,并详细注释:

import requests
from lxml import etree
from requests.packages import urllib3
import random, time
 
urllib3.disable_warnings()
 
 
def spider(pages, max_change_porxies_times=300):
  """
  抓取 XiciDaili.com 的 http类型-代理ip-和端口号
 
  将所有抓取的ip存入 raw_ips.csv 待处理, 可用 check_proxies() 检查爬取到的代理ip是否可用
  -----
  :param pages:要抓取多少页
  :return:无返回
  """
  s = requests.session()
  s.trust_env = False
  s.verify = False
  urls =com/nn/{}'
  proxies = {}
  try_times = 0
  for i in range(pages):
    url = urls.format(i + 1)
    s.headers = {
      'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
      'Accept-Encoding': 'gzip, deflate, br',
      'Accept-Language': 'zh-CN,zh;q=0.9',
      'Connection': 'keep-alive',
      'Referer': urls.format(i if i > 0 else ''),
      'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.75 Safari/537.36'}
    while True:
      content = s.get(url, headers=s.headers, proxies=proxies)
      time.sleep(random.uniform(1.5, 4)) # 每读取一次页面暂停一会,否则会被封
      if content.status_code == 503: # 如果503则ip被封,就更换ip
        proxies = get_proxies()
        try_times += 1
        print(f'第{str(try_times):0>3s}次变更,当前{proxies}')
        if try_times > max_change_porxies_times:
          print('超过最大尝试次数,连接失败!')
          return -1
        continue
      else:
        break # 如果返回码是200 ,就跳出while循环,对爬取的页面进行处理
 
    print(f'正在抓取第{i+1}页数据,共{pages}页')
    for j in range(2, 102): # 用简单的xpath提取http,host和port
      tree = etree.HTML(content.text)
      http = tree.xpath(f'//table[@id="ip_list"]/tr[{j}]/td[6]/text()')[0]
      host = tree.xpath(f'//table[@id="ip_list"]/tr[{j}]/td[2]/text()')[0]
      port = tree.xpath(f'//table[@id="ip_list"]/tr[{j}]/td[3]/text()')[0]
      check_proxies(http, host, port) # 检查提取的代理ip是否可用
 
 
def check_proxies(http, host, port, test_url='http://www.baidu.com'):
  """
  检测给定的ip信息是否可用
 
  根据http,host,port组成proxies,对test_url进行连接测试,如果通过,则保存在 ips_pool.csv 中
  :param http: 传输协议类型
  :param host: 主机
  :param port: 端口号
  :param test_url: 测试ip
  :return: None
  """
  proxies = {http: host + ':' + port}
  try:
    res = requests.get(test_url, proxies=proxies, timeout=2)
    if res.status_code == 200:
      print(f'{proxies}检测通过')
      with open('ips_pool.csv', 'a+') as f:
        f.write(','.join([http, host, port]) + '\n')
  except Exception as e: # 检测不通过,就不保存,别让报错打断程序
    print(e)
 
 
def check_local_ip(fn, test_url):
  """
  检查存放在本地ip池的代理ip是否可用
 
  通过读取fn内容,加载每一条ip对test_url进行连接测试,链接成功则储存在 ips_pool.csv 文件中
  :param fn: filename,储存代理ip的文件名
  :param test_url: 要进行测试的ip
  :return: None
  """
  with open(fn, 'r') as f:
    datas = f.readlines()
    ip_pools = []
  for data in datas:
    # time.sleep(1)
    ip_msg = data.strip().split(',')
    http = ip_msg[0]
    host = ip_msg[1]
    port = ip_msg[2]
    proxies = {http: host + ':' + port}
    try:
      res = requests.get(test_url, proxies=proxies, timeout=2)
      if res.status_code == 200:
        ip_pools.append(data)
        print(f'{proxies}检测通过')
        with open('ips_pool.csv', 'a+') as f:
          f.write(','.join([http, host, port]) + '\n')
    except Exception as e:
      print(e)
      continue
 
 
def get_proxies(ip_pool_name='ips_pool.csv'):
  """
  从ip池获得一个随机的代理ip
  :param ip_pool_name: str,存放ip池的文件名,
  :return: 返回一个proxies字典,形如:{'HTTPS': '106.12.7.54:8118'}
  """
  with open(ip_pool_name, 'r') as f:
    datas = f.readlines()
  ran_num = random.choice(datas)
  ip = ran_num.strip().split(',')
  proxies = {ip[0]: ip[1] + ':' + ip[2]}
  return proxies
 
 
if __name__ == '__main__':
  t1 = time.time()
  spider(pages=3400)
  t2 = time.time()
  print('抓取完毕,时间:', t2 - t1)
 
  # check_local_ip('raw_ips.csv','http://www.baidu.com')

以上就是python爬虫构建代理ip池抓取数据库的示例代码的详细内容,更多关于python爬虫构建代理ip池的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
Python装饰器入门学习教程(九步学习)
Jan 28 Python
python中pandas.DataFrame排除特定行方法示例
Mar 12 Python
python 利用栈和队列模拟递归的过程
May 29 Python
Python寻找两个有序数组的中位数实例详解
Dec 05 Python
对python打乱数据集中X,y标签对的方法详解
Dec 14 Python
Python零基础入门学习之输入与输出
Apr 03 Python
用python求一个数组的和与平均值的实现方法
Jun 29 Python
Python编程中类与类的关系详解
Aug 08 Python
浅谈Python3多线程之间的执行顺序问题
May 02 Python
Python中常见的数制转换有哪些
May 27 Python
Python中关于logging模块的学习笔记
Jun 03 Python
如何导出python安装的所有模块名称和版本号到文件中
Jun 05 Python
scrapy中如何设置应用cookies的方法(3种)
Sep 22 #Python
Python浮点型(float)运算结果不正确的解决方案
Sep 22 #Python
如何使用PyCharm引入需要使用的包的方法
Sep 22 #Python
python 如何区分return和yield
Sep 22 #Python
Python中三维坐标空间绘制的实现
Sep 22 #Python
Pyinstaller打包Scrapy项目的实现步骤
Sep 22 #Python
Python使用pickle进行序列化和反序列化的示例代码
Sep 22 #Python
You might like
关于Intype一些小问题的解决办法
2008/03/28 PHP
php MySQL与分页效率
2008/06/04 PHP
PHP对象转换为数组函数(递归方法)
2012/02/04 PHP
精美漂亮的php分页类代码
2013/04/02 PHP
PHP判断是否有Get参数的方法
2014/05/05 PHP
利用PHP fsockopen 模拟POST/GET传送数据的方法
2015/09/22 PHP
php实现单笔转账到支付宝功能
2018/10/09 PHP
tagName的使用,留一笔
2006/06/26 Javascript
让你的网站可编辑的实现js代码
2009/10/19 Javascript
JavaScript中常用的运算符小结
2012/01/18 Javascript
js实现iframe自动自适应高度的方法
2015/02/17 Javascript
JS+CSS实现的拖动分页效果实例
2015/05/11 Javascript
canvas实现弧形可拖动进度条效果
2017/05/11 Javascript
JS常用正则表达式总结【经典】
2017/05/12 Javascript
基于js 字符串indexof与search方法的区别(详解)
2017/12/04 Javascript
Swiper 4.x 使用方法(移动端网站的内容触摸滑动)
2018/05/17 Javascript
VeeValidate 的使用场景以及配置详解
2019/01/11 Javascript
Nodejs监控事件循环异常示例详解
2019/09/22 NodeJs
加速vue组件渲染之性能优化
2020/04/09 Javascript
vue3.0 项目搭建和使用流程
2021/03/04 Vue.js
在Python的Flask框架中实现全文搜索功能
2015/04/20 Python
python rsa 加密解密
2017/03/20 Python
Python学习小技巧之列表项的排序
2017/05/20 Python
python队列queue模块详解
2018/04/27 Python
详解Python最长公共子串和最长公共子序列的实现
2018/07/07 Python
Python中拆分字符串的操作方法
2019/07/23 Python
python实现多进程通信实例分析
2019/09/01 Python
python模式 工厂模式原理及实例详解
2020/02/11 Python
python实现的分层随机抽样案例
2020/02/25 Python
Python如何输出警告信息
2020/07/30 Python
Python测试框架:pytest学习笔记
2020/10/20 Python
python 实时调取摄像头的示例代码
2020/11/25 Python
python 批量将中文名转换为拼音
2021/02/07 Python
最新大学生创业计划书写作攻略
2014/04/02 职场文书
试了下Golang实现try catch的方法
2021/07/01 Golang
Spring Data JPA框架自定义Repository接口
2022/04/28 Java/Android