爬取西刺代理

生成请求头

#encoding = utf-8;
__all__ = ("Header");
import random; class Header(object):
'''请求头构造类'''
def __init__(self):
self.__user_agent = [
"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0)", #IE
"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0", # Fire_Fox
"Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.133 Safari/534.16", # Chrome
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.11 TaoBrowser/2.0 Safari/536.11", # taobao
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; QQDownload 732; .NET4.0C; .NET4.0E; LBBROWSER)", #猎豹
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36", #
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.57.2 (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2", # safarir
"Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.84 Safari/535.11 SE 2.X MetaSr 1.0", # 搜狐
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) ", # maxthon
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.122 UBrowser/4.0.3214.0 Safari/537.36" # uc
]; @property
def headers(self):
'''返回一个伪造后的hander'''
headers = {
"User-agent" : self.user_agent,
};
return headers; @property
def user_agent(self):
index = random.randint(0, len(self.__user_agent)-1);
return self.__user_agent[index]; def __new__(cls):
'''此类创建模式为单实例模式'''
if not hasattr(cls, "__instance"):
cls.__instance = super().__new__(cls);
return cls.__instance;
else:
return cls.__instance;

ip 模块类

#encoding = utf-8;
__all__ = ("IP_Model", "IP_List"); class IP_Model(object):
'''保存代理ip的全部内容'''
def __init__(self):
self._country = None;
self._addres = None; @property
def country(self):
'''
代理服务器所在国家
'''
return self._country; @country.setter
def country(self, ip_country):
if ip_country != None:
self._country = ip_country;
else:
self._country = None; @property
def ip(self):
'''
代理服务器的ip
'''
return self._ip; @ip.setter
def ip(self, new_ip):
self._ip = new_ip; @property
def port(self):
'''
访问端口号
'''
return self._port; @port.setter
def port(self, new_port):
self._port = new_port; @property
def addres(self):
'''
服务器所在省地址
'''
return self._addres; @addres.setter
def addres(self, new_addres):
if new_addres != None:
self._addres = new_addres;
else:
self._addres = None; @property
def http_type(self):
'''
请求类型
'''
return self._http_type; @http_type.setter
def http_type(self, type):
self._http_type = type; @property
def velocity(self):
'''服务器速度'''
return self._velocity; @velocity.setter
def velocity(self, http_velocity):
self._velocity = http_velocity; @property
def anonymous(self):
return self._anonymous; @anonymous.setter
def anonymous(self, anonymous_text):
if anonymous_text == "高匿":
self._anonymous = True;
else:
self._anonymous= False; def __str__(self):
'''
重新__str__方法,
:return: 返回格式化的IP_Model属性内容生成的字符串
'''
return (
"| country: {} |\n"
"| ip: {} |\n"
"| port: {} |\n"
"| address: {} |\n"
"| http_type: {} |\n"
"| velocity: {}|\n"
.format(self.country, self.ip, self.port, self.addres, self.http_type, self.velocity)
); def to_dict(self):
return {
"country" : self.country,
"ip" : self.ip,
"port" : self.port,
"addres" : self.addres,
"http_type" : self.http_type,
"velocity" : self.velocity
}; def from_dict(self,dict):
self.country = dict.get("country");
self.ip = dict.get("ip");
self.port = dict("port");
self.addres = dict.get("addres");
self.http_type = dict.get("http_type");
self.velocity = dict.get("velocity"); def get_ip_proxies(self):
proxies = None;
if self.http_type == "https":
proxies = { "https" : "{}:{}".format(self.ip, self.port)};
else:
proxies = {"http": "{}:{}".format(self.ip, self.port)};
return proxies; class IP_List(object):
def __init__(self):
self.http_list = None;
self.https_list = None;

 保存到csv

#encoding = utf-8
import pandas; '''
供simple_proxy使用的保存数据函数集
''' def to_pandas_DataFrame(ips_list):
'''
适配pandas 的数据类型, 将list表转换为pandas存储的数据类型
:param page_list:
:return: 返回panfas存储数据的类型
'''
page_map = map(lambda ip_model: ip_model.to_dict(), ips_list);
return pandas.DataFrame(list(page_map)); def to_csv(dicts):
to_pandas_DataFrame(dicts).to_csv("./ips_info.csv", mode="a", encoding="ANSI"); def read_csv(path, start, step):
'''
从csv的指定行开始读取对应行数的ip内容
:param path: csv文件路径名
:param start: 开始行
:param step: 每次读取的行数
:return: 返回对应的ip_list
'''
pass;

爬取西刺主体代码

# encoding = utf-8
__all__ = ("html_to_dom", "ProxyIPWorm");
import requests;
from header import Header;
from bs4 import BeautifulSoup;
from ip_model import IP_Model, IP_List;
import save;
import time;
import re; def simple_proxy(read_out):
'''
简单代理ip构建
:param read_out:
:return:
'''
pass; def html_to_dom(url, header, proxies=None):
'''
简单封装下requests
:param url: 访问url
:param header: 伪造的请求头
:param proxies: 是否使用代理ip
:return:
'''
if proxies != None:
response = requests.get(url, headers=header, proxies=proxies, verify=True);
else:
response = requests.get(url, headers=header, verify=True);
if response.status_code == 200:
response.encoding = "utf-8";
return BeautifulSoup(response.text, "html.parser");
else:
return None; def proxy(url, ips, log):
'''
使用代理ip访问指定服务器
:param url: 访问的服务器ip路径
:param ips: 携带http_list和https_list的服务器ip列表
:param log: 是否开启日志
:return: 返回生成的bs4的dom
'''
type = re.match(r"(.*):.*", url).group(1);
if ips == None:
raise RuntimeError("代理列表为空");
ip_list = None;
if type == "http":
ip_list = ips.http_list;
elif type == "https":
ip_list = ips.https_list;
else:
raise RuntimeError("不支持此类请求");
if log == True:
print("请求类型{}\n".format(type));
for ip in ip_list:
proxies = {type : "{}:{}".format(ip.ip, ip.port)};
print(proxies);
dom = html_to_dom(url, Header().headers, proxies);
if log == True:
print("当前ip:\n{}\n".format(ip));
if dom != None:
return dom; class ProxyIPWorm(object):
'''爬取代理ip'''
def __init__(self):
self.proxy_ip_html = "https://www.xicidaili.com/nn/";
self.dom_tree = html_to_dom(self.proxy_ip_html, Header().headers); @property
def start_page(self):
'''
开始页
:return:永远返回1
'''
return 1; @property
def end_page(self):
'''
获取公开的高匿ip的总页数
:return: 返回高匿ip页数
'''
page_dom = self.dom_tree.select(".pagination a");
self._end_page = page_dom[-2];
return int(self._end_page.text); def page_url(self, type, page):
'''
由给定整数生成对应西刺ip对应的页数的网址
:param page: 指定的页数
:return: 生成后的网址
'''
if page < 1 or page > self.end_page:
raise RuntimeError("页数大于总页数");
elif page == 1:
return "https://www.xicidaili.com/{}/".format(self.http_type(type));
else:
return "https://www.xicidaili.com/{}/{}".format(self.http_type(type) ,page); def http_type(self, type):
'''
根据http或https返回对应的西刺代理格式
:param type: hhtp 或 https
:return: 对应的西刺代理格式
'''
if type == "http":
return "wt";
elif type == "https":
return "wn";
else:
raise RuntimeError("type应该为http或https"); def get_page_ips(self, type, page):
'''
获取指定页的所有ip
:param type: ip类型 http 或 https
:param page: 爬取页面
:return:返回该页被ip_model封装的所有ip列表
'''
print(self.page_url(type ,page));
page_dom = html_to_dom(self.page_url(type ,page), Header().headers);
page_ips_dom = page_dom.select("table tr");
# print(page_ips_dom[0]);
ip_generator = (ip for ip in page_ips_dom[1:]);
ip_list = [];
for ip_dom in ip_generator:
ip_info = self.get_ip_info(ip_dom);
ip_list.append(ip_info);
return ip_list; def get_ip_info(self, ip_dom):
'''
获取指定的ip详细信息
:param ip_dom: 存有ip信息的html节点
:return: 返回ip_model结构的ipo封装类
'''
ip_info = IP_Model();
ip_td = ip_dom.select("td");
country = ip_td[0].img; ip_info.http_type = ip_td[5].text;
if country != None:
ip_info.country = str(country.get("alt"));
ip_info.addres = ip_td[3].text.split()[0];
ip_info.ip = ip_td[1].text;
ip_info.port = ip_td[2].text;
ip_info.anonymous = ip_td[4].text; ip_info.velocity = ip_td[6].div.get("title");
return ip_info; def get_pages_ips(self, type, start_page, end_page, save_in=save.to_csv):
'''
获取指定开始页到结束页的所有ip(包括结束页)
:param type: 请求为http还是https
:param start_page: 开始页面
:param end_page: 结束页
:param save_in: 如何保存到文件格式,是一个回调函数,默认保存入csv
:return:
'''
if start_page >= end_page:
raise RuntimeError("开始页大于等于结束页");
elif start_page < 1:
raise RuntimeError("开始页小于结束页");
elif end_page > self.end_page:
raise RuntimeError("结束页大于总页数");
else:
for page in range(start_page, end_page):
print("当前页:{}".format(page));
page_list = self.get_page_ips(page);
save_in(page_list);
time.sleep(10);
return page_list;

测试代码

if __name__ == "__main__":
test = ProxyIPWorm();
#
https_list = test.get_page_ips("https", 1);
http_list = test.get_page_ips("http", 1);
ips = IP_List();
ips.https_list = https_list;
ips.http_list = http_list;
dom = proxy("http://news.gzcc.cn/html/xiaoyuanxinwen/", ips, True);
print(dom);

python大作业的更多相关文章

  1. python大作业二

    一.存入csv 上次爬取到了所需要的内容,但是没有存入到csv中,这次存入了csv文件中,代码如下: import requests from bs4 import BeautifulSoup imp ...

  2. python大作业-图书管理系统

    #缺少循环执行和错误处理 #add()函数 添加了循环执行 #错误处理:regist()函数 登录和退出选择的时候添加了错误处理 import sys import importlib importl ...

  3. 数据库大作业--由python+flask

    这个是项目一来是数据库大作业,另一方面也算是再对falsk和python熟悉下,好久不用会忘很快. 界面相比上一个项目好看很多,不过因为时间紧加上只有我一个人写,所以有很多地方逻辑写的比较繁琐,如果是 ...

  4. Hadoop综合大作业

    Hadoop综合大作业 要求: 用Hive对爬虫大作业产生的文本文件(或者英文词频统计下载的英文长篇小说)词频统计. 用Hive对爬虫大作业产生的csv文件进行数据分析 1. 用Hive对爬虫大作业产 ...

  5. 爬虫综合大作业——网易云音乐爬虫 & 数据可视化分析

    作业要求来自于https://edu.cnblogs.com/campus/gzcc/GZCC-16SE2/homework/3075 爬虫综合大作业 选择一个热点或者你感兴趣的主题. 选择爬取的对象 ...

  6. 【大数据应用技术】作业十二|Hadoop综合大作业

    本次作业的要求来自:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE2/homework/3339 前言 本次作业是在<爬虫大作业>的基础上进行的 ...

  7. 程设大作业xjb写——魔方复原

    鸽了那么久总算期中过[爆]去[炸]了...该是时候写写大作业了 [总不能丢给他们不会写的来做吧 一.三阶魔方的几个基本定义 ↑就像这样,可以定义面的称呼:上U下D左L右R前F后B UD之间的叫E,LR ...

  8. python大数据工作流程

    本文作者:hhh5460 大数据分析,内存不够用怎么办? 当然,你可以升级你的电脑为超级电脑. 另外,你也可以采用硬盘操作. 本文示范了硬盘操作的一种可能的方式. 本文基于:win10(64) + p ...

  9. 大作业NABC分析结果

    大作业NABC分析结果 这次的大作业计划制作一款关于七巧板的游戏软件.关于编写的APP的NABC需求分析: N:需求 ,本款软件主要面向一些在校的大学生,他们在校空闲时间比较多,而且热衷于一些益智类游 ...

随机推荐

  1. ajax 三种数据格式

    1.JSON(格式要正确,可以引jar包操作) servlet代码 package com.hsp.action; import java.io.IOException; import java.io ...

  2. dup(dup2/dup3)

    readme man~ NAME dup, dup2, dup3 - duplicate a file descriptor SYNOPSIS #include <unistd.h> in ...

  3. ElasticSearch + Canal 开发千万级的实时搜索系统

    公司是做社交相关产品的,社交类产品对搜索功能需求要求就比较高,需要根据用户城市.用户ID昵称等进行搜索. 项目原先的搜索接口采用SQL查询的方式实现,数据库表采用了按城市分表的方式.但随着业务的发展, ...

  4. Linux内核笔记:epoll实现原理(一)

    一.说明 针对的内核版本为4.4.10. 本文只是我自己看源码的简单笔记,如果想了解epoll的实现,强烈推荐下面的文章: The Implementation of epoll(1) The Imp ...

  5. (50)Wangdao.com第七天_JavaScript 发展与简介

    一个完整的JavaScript 应该由以下三部分组成: ECMAScript DOM,全称Browser Object Model,即浏览器对象模型,主要处理浏览器窗口和框架 BOM,全称Docume ...

  6. PC_官网设计

    1. 头部 header 固定 的两种方式 固定定位 内容区 包裹,使用 overflow: hidden; 2. 动画第二次起效 缺少动画初始参数 3. 隐藏元素 display: none; vi ...

  7. React_基本原理_ajax

    React 基本原理 初始化显示界面 创建虚拟DOM树 渲染到 原生 DOM 树 绘制界面显示 更新界面 setState() 更新状态机 重新创建虚拟 DOM 树 新/旧树比较差异 (执行一次 DO ...

  8. SpringMVC的坑

    The request sent by the client was syntactically incorrect. 这个错误的原因是 因为 提交的表单数据和目标方法的入参不一致所导致   然后我就 ...

  9. java学习之路--I/O流

      java基础学习总结——流 一.JAVA流式输入/输出原理

  10. Oracle 基础概念

    数据库是一系列物理文件的集合(数据文件,控制文件,联机日志,参数文件等) --查询当前数据库名:select name from v$database; 数据库实例是一组Oracle后台进程/线程以及 ...