Python代理IP爬虫的新手使用教程


Posted in Python onSeptember 05, 2019

前言

Python爬虫要经历爬虫、爬虫被限制、爬虫反限制的过程。当然后续还要网页爬虫限制优化,爬虫再反限制的一系列道高一尺魔高一丈的过程。爬虫的初级阶段,添加headers和ip代理可以解决很多问题。

本人自己在爬取豆瓣读书的时候,就以为爬取次数过多,直接被封了IP.后来就研究了代理IP的问题.

(当时不知道什么情况,差点心态就崩了...),下面给大家介绍一下我自己代理IP爬取数据的问题,请大家指出不足之处.

问题

这是我的IP被封了,一开始好好的,我还以为是我的代码问题了

Python代理IP爬虫的新手使用教程

思路:

从网上查找了一些关于爬虫代理IP的资料,得到下面的思路

  1. 爬取一些IP,过滤掉不可用.
  2. 在requests的请求的proxies参数加入对应的IP.
  3. 继续爬取.
  4. 收工
  5. 好吧,都是废话,理论大家都懂,上面直接上代码...

思路有了,动手起来.

运行环境

Python 3.7, Pycharm

这些需要大家直接去搭建好环境...

准备工作

  1. 爬取IP地址的网站(国内高匿代理)
  2. 校验IP地址的网站
  3. 你之前被封IP的py爬虫脚本...

上面的网址看个人的情况来选取

爬取IP的完整代码

PS:简单的使用bs4获取IP和端口号,没有啥难度,里面增加了一个过滤不可用IP的逻辑

关键地方都有注释了

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Time : 2018/11/22 
# @Author : liangk
# @Site :
# @File : auto_archive_ios.py
# @Software: PyCharm


import requests
from bs4 import BeautifulSoup
import json


class GetIp(object):
 """抓取代理IP"""

 def __init__(self):
 """初始化变量"""
 self.url = 'http://www.xicidaili.com/nn/'
 self.check_url = 'https://www.ip.cn/'
 self.ip_list = []

 @staticmethod
 def get_html(url):
 """请求html页面信息"""
 header = {
  'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36'
 }
 try:
  request = requests.get(url=url, headers=header)
  request.encoding = 'utf-8'
  html = request.text
  return html
 except Exception as e:
  return ''

 def get_available_ip(self, ip_address, ip_port):
 """检测IP地址是否可用"""
 header = {
  'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36'
 }
 ip_url_next = '://' + ip_address + ':' + ip_port
 proxies = {'http': 'http' + ip_url_next, 'https': 'https' + ip_url_next}
 try:
  r = requests.get(self.check_url, headers=header, proxies=proxies, timeout=3)
  html = r.text
 except:
  print('fail-%s' % ip_address)
 else:
  print('success-%s' % ip_address)
  soup = BeautifulSoup(html, 'lxml')
  div = soup.find(class_='well')
  if div:
  print(div.text)
  ip_info = {'address': ip_address, 'port': ip_port}
  self.ip_list.append(ip_info)

 def main(self):
 """主方法"""
 web_html = self.get_html(self.url)
 soup = BeautifulSoup(web_html, 'lxml')
 ip_list = soup.find(id='ip_list').find_all('tr')
 for ip_info in ip_list:
  td_list = ip_info.find_all('td')
  if len(td_list) > 0:
  ip_address = td_list[1].text
  ip_port = td_list[2].text
  # 检测IP地址是否有效
  self.get_available_ip(ip_address, ip_port)
 # 写入有效文件
 with open('ip.txt', 'w') as file:
  json.dump(self.ip_list, file)
 print(self.ip_list)


# 程序主入口
if __name__ == '__main__':
 get_ip = GetIp()
 get_ip.main()

使用方法完整代码

PS: 主要是通过使用随机的IP来爬取,根据request_status来判断这个IP是否可以用.

为什么要这样判断?

主要是虽然上面经过了过滤,但是不代表在你爬取的时候是可以用的,所以还是得多做一个判断.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Time : 2018/11/22 
# @Author : liangk
# @Site :
# @File : get_douban_books.py
# @Software: PyCharm

from bs4 import BeautifulSoup
import datetime
import requests
import json
import random

ip_random = -1
article_tag_list = []
article_type_list = []


def get_html(url):
 header = {
  'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36'
 }
 global ip_random
 ip_rand, proxies = get_proxie(ip_random)
 print(proxies)
 try:
  request = requests.get(url=url, headers=header, proxies=proxies, timeout=3)
 except:
  request_status = 500
 else:
  request_status = request.status_code
 print(request_status)
 while request_status != 200:
  ip_random = -1
  ip_rand, proxies = get_proxie(ip_random)
  print(proxies)
  try:
   request = requests.get(url=url, headers=header, proxies=proxies, timeout=3)
  except:
   request_status = 500
  else:
   request_status = request.status_code
  print(request_status)
 ip_random = ip_rand
 request.encoding = 'gbk'
 html = request.content
 print(html)
 return html


def get_proxie(random_number):
 with open('ip.txt', 'r') as file:
  ip_list = json.load(file)
  if random_number == -1:
   random_number = random.randint(0, len(ip_list) - 1)
  ip_info = ip_list[random_number]
  ip_url_next = '://' + ip_info['address'] + ':' + ip_info['port']
  proxies = {'http': 'http' + ip_url_next, 'https': 'https' + ip_url_next}
  return random_number, proxies


# 程序主入口
if __name__ == '__main__':
 """只是爬取了书籍的第一页,按照评价排序"""
 start_time = datetime.datetime.now()
 url = 'https://book.douban.com/tag/?view=type&icn=index-sorttags-all'
 base_url = 'https://book.douban.com/tag/'
 html = get_html(url)
 soup = BeautifulSoup(html, 'lxml')
 article_tag_list = soup.find_all(class_='tag-content-wrapper')
 tagCol_list = soup.find_all(class_='tagCol')

 for table in tagCol_list:
  """ 整理分析数据 """
  sub_type_list = []
  a = table.find_all('a')
  for book_type in a:
   sub_type_list.append(book_type.text)
  article_type_list.append(sub_type_list)

 for sub in article_type_list:
  for sub1 in sub:
   title = '==============' + sub1 + '=============='
   print(title)
   print(base_url + sub1 + '?start=0' + '&type=S')
   with open('book.text', 'a', encoding='utf-8') as f:
    f.write('\n' + title + '\n')
    f.write(url + '\n')
   for start in range(0, 2):
    # (start * 20) 分页是0 20 40 这样的
    # type=S是按评价排序
    url = base_url + sub1 + '?start=%s' % (start * 20) + '&type=S'
    html = get_html(url)
    soup = BeautifulSoup(html, 'lxml')
    li = soup.find_all(class_='subject-item')
    for div in li:
     info = div.find(class_='info').find('a')
     img = div.find(class_='pic').find('img')
     content = '书名:<%s>' % info['title'] + ' 书本图片:' + img['src'] + '\n'
     print(content)
     with open('book.text', 'a', encoding='utf-8') as f:
      f.write(content)

 end_time = datetime.datetime.now()
 print('耗时: ', (end_time - start_time).seconds)

为什么选择国内高匿代理!

Python代理IP爬虫的新手使用教程

总结

使用这样简单的代理IP,基本上就可以应付在爬爬爬着被封IP的情况了.而且没有使用自己的IP,间接的保护?!?!

大家有其他的更加快捷的方法,欢迎大家可以拿出来交流和讨论,谢谢。

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。

Python 相关文章推荐
python self,cls,decorator的理解
Jul 13 Python
python中的对象拷贝示例 python引用传递
Jan 23 Python
python使用正则搜索字符串或文件中的浮点数代码实例
Jul 11 Python
Python调用命令行进度条的方法
May 05 Python
Python matplotlib通过plt.scatter画空心圆标记出特定的点方法
Dec 13 Python
PyQt打开保存对话框的方法和使用详解
Feb 27 Python
Flask配置Cors跨域的实现
Jul 12 Python
Python使用Opencv实现图像特征检测与匹配的方法
Oct 30 Python
基于python实现文件加密功能
Jan 06 Python
使用TFRecord存取多个数据案例
Feb 17 Python
pandas和spark dataframe互相转换实例详解
Feb 18 Python
Python实现验证码识别
Jun 15 Python
关于Python内存分配时的小秘密分享
Sep 05 #Python
python global关键字的用法详解
Sep 05 #Python
python requests证书问题解决
Sep 05 #Python
Python使用scipy模块实现一维卷积运算示例
Sep 05 #Python
Python图像处理模块ndimage用法实例分析
Sep 05 #Python
Pycharm+django2.2+python3.6+MySQL实现简单的考试报名系统
Sep 05 #Python
PyCharm搭建Spark开发环境的实现步骤
Sep 05 #Python
You might like
php做下载文件的实现代码及文件名中乱码解决方法
2011/02/03 PHP
jQuery 源码分析笔记
2011/05/25 PHP
fetchAll()与mysql_fetch_array()的区别详解
2013/06/05 PHP
详解提高使用Java反射的效率方法
2019/04/29 PHP
如何在PHP中读写文件
2020/09/07 PHP
javascript中检测变量的类型的代码
2010/12/28 Javascript
js动态加载以及确定加载完成的代码
2011/07/31 Javascript
javascript firefox 自动加载iframe 自动调整高宽示例
2013/08/27 Javascript
简单实用的反馈表单无刷新提交带验证
2013/11/15 Javascript
javascript使用正则控制input输入框允许输入的值方法大全
2014/06/19 Javascript
jquery中$(#form :input)与$(#form input)的区别
2014/08/18 Javascript
影响jQuery使用的14个方面
2014/09/01 Javascript
JavaScript中的关联数组问题
2015/03/04 Javascript
jquery UI Datepicker时间控件的使用及问题解决
2016/04/28 Javascript
详解百度百科目录导航树小插件
2017/01/08 Javascript
AngularJS改变元素显示状态
2017/04/20 Javascript
bootstrap3中container与container_fluid外层容器的区别讲解
2017/12/04 Javascript
Angular实现的table表格排序功能完整示例
2017/12/22 Javascript
微信小程序自定义菜单切换栏tabbar组件代码实例
2019/12/30 Javascript
js实现鼠标拖拽div左右滑动
2020/01/15 Javascript
JS通用方法触发点击事件代码实例
2020/02/17 Javascript
JavaScript实现刮刮乐效果
2020/11/01 Javascript
使用Python生成url短链接的方法
2015/05/04 Python
Python编程中NotImplementedError的使用方法
2018/04/21 Python
Django中反向生成models.py的实例讲解
2018/05/30 Python
python3实现字符串的全排列的方法(无重复字符)
2018/07/07 Python
PyQt5高级界面控件之QTableWidget的具体使用方法
2020/02/23 Python
基于css3 animate制作绚丽的动画效果
2015/11/24 HTML / CSS
温泉秘密:Onsen Secret
2020/07/06 全球购物
高三历史教学反思
2014/01/09 职场文书
青年教师典范事迹材料
2014/01/31 职场文书
人事部岗位职责范本
2014/03/05 职场文书
社区娱乐活动方案
2014/08/21 职场文书
2015年个人现实表现材料
2014/12/10 职场文书
护士爱岗敬业心得体会
2016/01/25 职场文书
mysql外连接与内连接查询的不同之处
2021/06/03 MySQL