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

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
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池抓取数据库的示例代码的更多相关文章

  1. Python 爬虫的代理 IP 设置方法汇总

    本文转载自:Python 爬虫的代理 IP 设置方法汇总 https://www.makcyun.top/web_scraping_withpython15.html 需要学习的地方:如何在爬虫中使用 ...

  2. python爬虫之分析Ajax请求抓取抓取今日头条街拍美图(七)

    python爬虫之分析Ajax请求抓取抓取今日头条街拍美图 一.分析网站 1.进入浏览器,搜索今日头条,在搜索栏搜索街拍,然后选择图集这一栏. 2.按F12打开开发者工具,刷新网页,这时网页回弹到综合 ...

  3. python多线程建立代理ip池

    之前有写过用单线程建立代理ip池,但是大家很快就会发现,用单线程来一个个测试代理ip实在是太慢了,跑一次要很久才能结束,完全无法忍受.所以这篇文章就是换用多线程来建立ip池,会比用单线程快很多.之所以 ...

  4. Python爬虫之-动态网页数据抓取

    什么是AJAX: AJAX(Asynchronouse JavaScript And XML)异步JavaScript和XML.过在后台与服务器进行少量数据交换,Ajax 可以使网页实现异步更新.这意 ...

  5. Python爬虫实战:使用Selenium抓取QQ空间好友说说

    前面我们接触到的,都是使用requests+BeautifulSoup组合对静态网页进行请求和数据解析,若是JS生成的内容,也介绍了通过寻找API借口来获取数据. 但是有的时候,网页数据由JS生成,A ...

  6. Python爬虫入门教程 45-100 Charles抓取兔儿故事-下载小猪佩奇故事-手机APP爬虫部分

    1. Charles抓取兔儿故事背景介绍 之前已经安装了Charles,接下来我将用两篇博客简单写一下关于Charles的使用,今天抓取一下兔儿故事里面关于小猪佩奇的故事. 爬虫编写起来核心的重点是分 ...

  7. [Python爬虫] 之八:Selenium +phantomjs抓取微博数据

    基本思路:在登录状态下,打开首页,利用高级搜索框输入需要查询的条件,点击搜索链接进行搜索.如果数据有多页,每页数据是20条件,读取页数 然后循环页数,对每页数据进行抓取数据. 在实践过程中发现一个问题 ...

  8. Python爬虫入门教程 46-100 Charles抓取手机收音机-手机APP爬虫部分

    1. 手机收音机-爬前叨叨 今天选了一下,咱盘哪个APP呢,原计划是弄荔枝APP,结果发现竟然没有抓到数据,很遗憾,只能找个没那么圆润的了.搜了一下,找到一个手机收音机 下载量也是不错的. 2. 爬虫 ...

  9. 爬虫入门到放弃系列05:从程序模块设计到代理IP池

    前言 上篇文章吧啦吧啦讲了一些有的没的,现在还是回到主题写点技术相关的.本篇文章作为基础爬虫知识的最后一篇,将以爬虫程序的模块设计来完结. 在我漫(liang)长(nian)的爬虫开发生涯中,我通常将 ...

随机推荐

  1. 使用HTML的基本结构创建网页

    1.       网页的扩展名--html或htm 2.       如何新建网页? 步骤1: 在电脑的空白处,右键选择-->新建--文本文档 步骤2: 把txt的扩展名,改成html或htm, ...

  2. 树状数组(BIT)—— 一篇就够了

    树状数组(BIT)-- 一篇就够了 前言.内容梗概 本文旨在讲解: 树状数组的原理(起源,原理,模板代码与需要注意的一些知识点) 树状数组的优势,缺点,与比较(eg:线段树) 树状数组的经典例题及其技 ...

  3. 代码质量管理平台之SonarQube安装部署

    一.简介 Sonar是一个用于代码质量管理的开放平台,通过插件机制,sonar可以收集不同的测试工具,代码分析工具,以及持续集成工具.与持续集成工具(比如jenkins)不同,sonar并不是简单地把 ...

  4. day48 Pyhton 数据库Mysql 05

    一内容回顾 insert insert into 表名 (字段名)  values (值) insert into 表名 values (有多少个字段写多少个值) insert into 表名 val ...

  5. fastdfs之同一台storage server下包含多个store path

    一,查看本地centos的版本 [root@localhost lib]# cat /etc/redhat-release CentOS Linux release 8.1.1911 (Core) 说 ...

  6. qemu-kvm安装and配置桥接和SR-IOV

    kvm和docker的区别:kvm是全虚拟化,需要模拟各种硬件,docker是容器,共享宿主机的CPU,内存,swap等.本文安装的qemu-kvm属于kvm虚拟化,其中:kvm负责cpu虚拟化和内存 ...

  7. poj3178 Roping the Field (计算几何 + dp)

    Roping the Field Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 858   Accepted: 250 De ...

  8. JavaWeb中的域对象

    域对象:可以在不同Servlet之间传递数据的对象,就是域对象,它们内置了map集合,都有setAttribute和getAttribute方法: Java Web有ServletContext.Se ...

  9. JS里的小细节,持续更新

    判断把值定为 false 集合 JavaScript里把 null.undefined.0.''.NaN 都视为false,而其他值一概为 true Map Map是一组键值对的结构,具有极快的查找速 ...

  10. forword与redirect

    1.从地址栏显示来说 forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器.浏览器根本不知道服务器发送的内容从哪里来的,所以它的地 ...