上篇博客地址python代理池的构建2——代理ip是否可用的处理和检查

一、基础爬虫模块(Base_spider.py)

#-*-coding:utf-8-*-
'''
目标: 实现可以指定不同URL列表,分组的XPATH和详情的XPATH,从不同页面上提取代理的IP,端口号和区域的通用爬虫;
步骤:
1.在base_ spider.py文件中,定义 一个BaseSpider类, 继承object 2.提供三个类成员变量: urls:代理IP网址的URL的列表 group_ xpath:分组XPATH,获取包含代理IP信息标签列表的XPATH detail. xpath:组内XPATH,获取代理IP详情的信息XPATH,格式为: {'ip':'xx', 'pot':'xx','area':'xx'} 3.提供初始方法,传入爬虫URL列表,分组XPATH,详情(组内)XPATH4.对外提供-个获取代理IP的方法,遍历URL列表,获取URL 根据发送请求,获取页面数据 解析页面,提取数据,封装为Proxy对象 返回Proxy对象列表 ''' import requests
import sys
from lxml import etree
sys.path.append("..") #提供要导入的模块路径,之前博客讲过怎么使用
sys.path.append("../..")
from utils.http import get_requests_headers
from domain import Proxy class BaseSpider(object): #定义一个最基础的爬虫,后面爬取专门网站的爬虫继承这个基础爬虫
urls = []
group_xpath = '' #因为我们用的lxml模块解析页面,所以要传入分组xpath和细节xpath
detail_xpath = {} #这个细节xpath就是ip在页面的位置,端口在页面的位置等等 def __init__(self,urls=[],group_xpath='',detail_xpath={}):
if urls:
self.urls = urls if group_xpath:
self.group_xpath = group_xpath if detail_xpath:
self.detail_xpath = detail_xpath def get_page_from_url(self,url):
response = requests.get(url,headers=get_requests_headers())
#这个get_requests_headers方法是获取一个随机请求头,之前http.py模块定义过这个方法
return response.content def get_first_list(self,li=[]):
if len(li)!=0:
return li[0]
else :
return '' def get_proxies_from_page(self,page):
#这个就是把HTML页面给lxml,让它解析
element = etree.HTML(page) trs = element.xpath(self.group_xpath)
#print(trs)
for tr in trs:
#tr.xpath(self.detail_xpath['ip'])因为这一部分返回的是一个列表,而且如果我们直接写
#tr.xpath(self.detail_xpath['ip'])[0],如果这个列表为空,他就会报错导致程序异常终止
ip = self.get_first_list(tr.xpath(self.detail_xpath['ip']))
port = self.get_first_list(tr.xpath(self.detail_xpath['port']))
area = self.get_first_list(tr.xpath(self.detail_xpath['area']))
proxy = Proxy(ip,port,area=area)
print(proxy.__dict__) #这个dict函数就是把对象转化成字典类型输出,python内部函数
yield proxy #函数有了这个关键字,函数就是一个生成器函数。上篇博客讲过,会挂一下链接 def get_proxies(self):
for url in self.urls:
# print(url)
page = self.get_page_from_url(url)
# print(page)
proxies = self.get_proxies_from_page(page)
yield from proxies if __name__ == '__main__': #用于测试这个这个模块
# config = {
# 'urls':{'http://www.ip3366.net/?stype=1&page={}'.format(i) for i in range(1,3)},
# 'group_xpath':'//*[@id="list"]/table/tbody/tr',
# 'detail_xpath':{
# 'ip':'./td[1]/text()',
# 'port':'./td[2]/text()',
# 'area':'./td[6]/text()'
# }
# }
#
# spider = BaseSpider(**config)
# for proxy in spider.get_proxies():
# print(proxy)
url = 'http://www.66ip.cn/4.html'
response = requests.get(url,headers=get_requests_headers())
print(response.content.decode('GBK'))

python 引用(import)文件夹下的py文件

二、专门针对几个网站的爬虫(proxy_spiders.py)

#-*-coding:utf-8-*-
from base_spider import BaseSpider class XiciSpider(BaseSpider):
urls = {'https://www.xicidaili.com/nn/{}'.format(i) for i in range(1,2)}
group_xpath = '//*[@id="ip_list"]/tr[position()>1]'
detail_xpath = {
'ip':'./td[2]/text()',
'port':'./td[3]/text()',
'area':'./td[4]/a/text()'
} class ProxylistplusSpider(BaseSpider):
urls = {'https://list.proxylistplus.com/Fresh-HTTP-Proxy-List-{}'.format(i) for i in range(1,2)}
group_xpath = '//*[@id="page"]/table[2]/tr[position()>5]'
detail_xpath = {
'ip':'./td[2]/text()',
'port':'./td[3]/text()',
'area':'./td[5]/text()'
} class KuaidailiSpider(BaseSpider):
urls = {'https://www.kuaidaili.com/free/inha/{}'.format(i) for i in range(1,4)}
group_xpath = '//*[@id="list"]/table/tbody/tr'
detail_xpath = {
'ip':'./td[1]/text()',
'port':'./td[2]/text()',
'area':'./td[5]/text()' } class ip66Spider(BaseSpider):
urls = {'http://www.66ip.cn/{}.html'.format(i) for i in range(1,4)}
group_xpath = '//*[@id="main"]/div/div[1]/table/tr[position()>1]'
detail_xpath = {
'ip':'./td[1]/text()',
'port':'./td[2]/text()',
'area':'./td[3]/text()'
} if __name__ == '__main__':
pass
# spider = XiciSpider()
# spider = ProxylistplusSpider()
# spider = KuaidailiSpider()
# spider = ip66Spider()
# for proxy in spider.get_proxies():
# print(proxy)

我写的时候就没遇到反爬。。。。我也不知道为啥。。。。我就传了一个请求头headers

三、运行这几个爬虫(run_spiders.py)

#-*-coding:utf-8-*-
import sys
import importlib
import schedule
import time
from gevent import monkey
monkey.patch_all() #打上猴子补丁,这个我博客下面有这一方面解释链接 from gevent.pool import Pool #导入协程池
#可能有人会问为什么要用协程,因为requests.get()请求的时候会等待时间,我们可以利用这一部分时间做其他事情
sys.path.append("../..")
sys.path.append("..")
from settings import SPIDERS
from proxy_validate.httpbin_validator import check_proxy
from db.mongo_pool import MongoPool #要把可用代理IP存入mongodb数据库
from utils.log import logger
from settings import RUN_SPIDERS_INTERVAL #这些都是settings.py模块的一些变量 class RunSpiders(object): def __init__(self):
self.mongo_pool = MongoPool() #创建一个数据库对象,这个是我们写的模块,可以看python代理池的构建4——mongdb数据库的增删改查
self.coroutine_pool = Pool() #创建协程池 def get_spider_from_settings(self):
for full_class_name in SPIDERS: #下面这一部分就是动态导入模块,我会给出相应博客链接去解释他
module_name,class_name=full_class_name.rsplit('.',maxsplit=1)
module = importlib.import_module(module_name)
clss = getattr(module,class_name)
spider = clss()
#print(spider)
yield spider def run(self):
spiders = self.get_spider_from_settings() for spider in spiders: #开启多协程去分别运行多个爬虫
self.coroutine_pool.apply_async(self.run_one,args=(spider,)) self.coroutine_pool.join() #等全部爬虫都运行完,再结束这个函数 def run_one(self,spider):
try: #try一下,以防某个爬虫失败导入异常,从而程序异常结束
for proxy in spider.get_proxies():
proxy = check_proxy(proxy)
if proxy.speed != -1:
self.mongo_pool.insert_one(proxy) #这个就是把这一个代理ip信息插入到数据库里面
except Exception as ex:
logger.exception(ex) @classmethod #定义一个类方法,之后可以通过类名来调用
def start(cls): #这个cls参数,是它自己就带的
rs = RunSpiders()
rs.run()
schedule.every(RUN_SPIDERS_INTERVAL).hours.do(rs.run)
#这个意思就是每隔RUN_SPIDERS_INTERVAL小时,就执行一遍rs.run函数
while True:
schedule.run_pending() #这个就是检查时间到两个小时了没
time.sleep(60) if __name__ == '__main__': #检查本模块是否可用
RunSpiders.start()
# rs = RunSpiders()
# rs.run()

四、关于代码一些问题解决链接:

协程gevent模块和猴子补丁

python中schedule模块的简单使用 || importlib.import_module动态导入模块

Python中“*”和“**”的用法 || yield的用法 || ‘$in’和'$nin' || python @property的含义

python代理池的构建4——mongdb数据库的增删改查

五、python代理池的构建的其他链接

python代理池的构建5——对mongodb数据库里面代理ip检查

python代理池的构建4——mongdb数据库的增删改查

python代理池的构建2——代理ip是否可用的处理和检查

python代理池的构建1——代理IP类的构建,以及配置文件、日志文件、requests请求头

python代理池的构建3——爬取代理ip的更多相关文章

  1. python代理池的构建5——对mongodb数据库里面代理ip检查

    上一篇博客地址:python代理池的构建4--mongdb数据库的增删改查 一.对数据库里面代理ip检查(proxy_test.py) #-*-coding:utf-8-*- ''' 目的:检查代理I ...

  2. python代理池的构建4——mongdb数据库的增删改查

    上一篇博客地址:python代理池的构建3--爬取代理ip 一.mongdb数据库的增删改查(Mongo_pool.py) #-*-coding:utf-8-*- ''' 实现代理池的数据库模块 ●作 ...

  3. python代理池的构建2——代理ip是否可用的处理和检查

    上一篇博客地址:python代理池的构建1--代理IP类的构建,以及配置文件.日志文件.requests请求头 一.代理ip是否可用的处理(httpbin_validator.py) #-*-codi ...

  4. python代理池的构建1——代理IP类的构建,以及配置文件、日志文件、requests请求头

    一.整体结构 二.代理IP类的构建(domain.py文件) ''' 实现_ init_ 方法, 负责初始化,包含如下字段: ip: 代理的IP地址 port:代理IP的端口号 protocol: 代 ...

  5. Python爬虫-代理池-爬取代理入库并测试代理可用性

    目的:建立自己的代理池.可以添加新的代理网站爬虫,可以测试代理对某一网址的适用性,可以提供获取代理的 API. 整个流程:爬取代理 ----> 将代理存入数据库并设置分数 ----> 从数 ...

  6. python爬虫爬取代理IP

    # #author:wuhao # #--*------------*-- #-****#爬取代理IP并保存到Excel----#爬取当日的代理IP并保存到Excel,目标网站xicidaili.co ...

  7. 使用Selenium&PhantomJS的方式爬取代理

    前面已经爬取了代理,今天我们使用Selenium&PhantomJS的方式爬取快代理 :快代理 - 高速http代理ip每天更新. 首先分析一下快代理,如下 使用谷歌浏览器,检查,发现每个代理 ...

  8. Python爬虫学习三------requests+BeautifulSoup爬取简单网页

    第一次第一次用MarkDown来写博客,先试试效果吧! 昨天2018俄罗斯世界杯拉开了大幕,作为一个伪球迷,当然也得为世界杯做出一点贡献啦. 于是今天就编写了一个爬虫程序将腾讯新闻下世界杯专题的相关新 ...

  9. 初识python 之 爬虫:使用正则表达式爬取“糗事百科 - 文字版”网页数据

    初识python 之 爬虫:使用正则表达式爬取"古诗文"网页数据 的兄弟篇. 详细代码如下: #!/user/bin env python # author:Simple-Sir ...

随机推荐

  1. 十三:SQL注入之MYSQL注入

    MYSQL注入中首先要明确当前注入点权限,高权限注入时有更多的攻击手法,有的能直接进行getshell操作,其中也会遇到很多的阻碍,相关防御手法也要明确,所谓知己知彼,百战不殆.作为安全开发工作者,攻 ...

  2. kubernets之计算资源

    一  为pod分配cpu,内存以及其他的资源 1.1  创建一个pod,同时为这个pod分配内存以及cpu的资源请求量 apiVersion: v1 kind: Pod metadata: name: ...

  3. 基础练习(上) - 蓝桥杯(Python实现)

    闰年判断: 题目: 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 给定一个年份,判断这一年是不是闰年. 当以下情况之一满足时,这一年是闰年: 1. 年份是4的倍数而不是100的倍数 ...

  4. 如何在windows开机画面里隐藏用户

    当开机的时候都会在欢迎屏幕中显示一个账户或者多个已经建立的账户,通常还会显示登录的用户名,我们可以通过修改注册表实现把某个用户隐藏,具体方法如下:http://hi.baidu.com/liminsu ...

  5. 大数据系列1:一文初识Hdfs

    最近有位同事经常问一些Hadoop的东西,特别是Hdfs的一些细节,有些记得不清楚,所以趁机整理一波. 会按下面的大纲进行整理: 简单介绍Hdfs 简单介绍Hdfs读写流程 介绍Hdfs HA实现方式 ...

  6. scrapy框架基于管道的持久化存储

    scrapy框架的使用 基于管道的持久化存储的编码流程 在爬虫文件中数据解析 将解析到的数据封装到一个叫做Item类型的对象 将item类型的对象提交给管道 管道负责调用process_item的方法 ...

  7. 浅谈自动化构建之grunt

    自动化构建 开发行业的自动化构建 一句话把源代码转化为生产代码,作用是脱离运行环境兼容带来的问题开发阶段使用提高效率的语法,规范 和标准,构建转换那些不被支持的特性转化成能够执行的代码. 一.简单的自 ...

  8. 树莓派安装 Ubuntu 20.04 LTS 碰壁指南

    树莓派安装 Ubuntu 20.04 LTS 碰壁指南 设备 Raspberry 4B 4+32G 系统 Ubuntu 20.04 LTS 1.镜像下载与烧录 镜像下载地址:https://cdima ...

  9. 让源码包apache服务被服务管理命令识别

    在默认情况下,源码包服务是不能被系统的服务管理命令所识别和管理的,但是如果我们做一些设定,则也是可以让源码包服务被系统的服务管理命令所识别和管理的.不过笔者并不推荐大家这样做, 因为这会让本来区别很明 ...

  10. E4.IO.pry/0-IO.break!/1动态打点调试

    IO.pry/0 IO.inspect只能在静态地打印指定的变量,Elixir的shell还可以使用IO.pry/0与IO.break!/1实现更灵活的调试方法. 假如你想查看一下函数的某个位置到底发 ...