爬虫-1-基础和urllib

爬虫基础

一、爬虫介绍

什么是爬虫

爬虫:网络爬虫又称为网络蜘蛛,网络蚂蚁,网络机器人等,可以自动化浏览网络中的信息,当然浏览信息的时候需要按照我们的规定的规则进行,这些规则称之为网络爬虫算法,使用python可以很方便的写出爬虫程序,进行互联网信息的自动化检索

网 : 互联网
蜘蛛网: 互联网理解为蜘蛛网
爬虫: 蜘蛛

为什么学习爬虫
	私人定制一个搜索引擎,并且可以对搜索引擎的数采集工作原理进行更深层次地理解
	获取更多的数据源,并且这些数据源可以按我们的目的进行采集,去掉很多无关数据
	更好的进行seo(搜索引擎优化)  

网络爬虫的组成
	控制节点: 叫做爬虫中央控制器,主要负责根据URL地址分配线程,并调用爬虫节点进行具体爬行
	爬虫节点: 按照相关算法,对网页进行具体爬行,主要包括下载网页以及对网页的文本处理,爬行后会将对应的爬行结果存储到对应的资源库中
	资源库构成: 存储爬虫爬取到的响应数据,一般为数据库
	
爬虫设计思路
	首先确定需要爬取的网页URL地址
	通过HTTP协议来获取对应的HTML页面
	提取html页面里的有用数据
		如果是需要的数据就保存起来
		如果是其他的URL,那么就执行第二部
	  

Python爬虫的优势

PHP: 虽然是世界上最好的语言,但是天生不是干爬虫的命,php对多线程,异步支持不足,并发不足,爬虫是工具性程序,对速度和效率要求较高。

Java: 生态圈完善,是Python最大的对手,但是java本身很笨重,代码量大,重构成本比较高,任何修改都会导致大量的代码的变动.最要命的是爬虫需要经常修改部分代码
# 爬虫 =>  反爬  => 反反爬 => 反反反爬...

C/C++: 运行效率和性能几乎最强,但是学习成本非常高,代码成型较慢,能用C/C++写爬虫,说明能力很强,但不是最正确的选择.
    
# JS: DOM,事件,Ajax
Python: 语法优美,代码简洁,开发效率高,三方模块多,调用其他接口也方便, 有强大的爬虫Scrapy,以及成熟高效的scrapy-redis分布策略

Python爬虫需要掌握什么

Python基础语法
HTML基础

1.如何抓取页面: 
	HTTP请求处理,urllib处理后的请求可以模拟浏览器发送请求,获取服务器响应文件
2.解析服务器响应的内容: 
	re,xpath,BeautifulSoup4,jsonpath,pyquery 
	目的是使用某种描述性语法来提取匹配规则的数据
	
如何采取动态html,验证码处理:
	通用的动态页面采集, Selenium+headless(无界面浏览器),模拟真实浏览器加载js,ajax等非静态页面数据

Scrapy框架
	国内常见的框架Scrapy,Pyspider
	高定制性高性能(异步网络框架twisted),所以数据下载速度非常快,提供了数据存储,数据下载,提取规则等组件
	(异步网络框架twisted类似tornado(和Django,Flask相比的优势是高并发,性能较强的服务器框架))

分布式策略 
	scrapy-redis
	在Scrapy的基础上添加了一套以redis数据库为核心的一套组件,让scrapy框架支持分布式的功能,主要在redis里做请求指纹去重,请求分配,数据临时存储
	MySql(持久化), Redis, Mongodb(缓存,速度快)
	

爬虫与反爬虫与反反爬虫三角之争

最头痛的人
	爬虫做到最后, 最头痛的不是复杂的页面, 也不是海量的数据, 而是网站另一头的反爬虫人员
	
应对反爬虫策略
	User-Agent
	代理IP
	验证码:打码平台
	动态数据加载
	加密数据
	
是否需要反爬虫
	机器成本+人力成本 >  数据价值,就不反了,一般做到封IP就可以
	服务器压力
	面子的战争
	
爬虫和反爬虫之间的战争, 最后一定是爬虫胜利

网络爬虫类型

通用网络爬虫
	概念:搜索引擎用的爬虫系统
	用户群体:搜索引擎用的爬虫系统
	目标:尽可能把互联网上的所有网页下载下来,放到本地服务器里形成备份,再对这些网页做相关处理(提取关键字,去掉广告等),最后提供一个用户检测接口 
	
	抓取流程: 
		首先选取一部分已有的URL,把这些URL放到待爬队列
		从队列里提取这些URL,然后解析DNS得到主机ip,然后去这个IP对应的服务器里下载HTML页面,保存到搜索引擎的本地服务器里,之后把爬过的URL放入到以爬取队列
		分析这些网页内容,找出网页里的URl连接,继续执行第二步,直到爬取条件结束
	
	搜索引擎如何获取一个新网站的URL:
		主动向搜索引擎提交网址(百度站长平台):http://zhanzhang.baidu.com/site/index?action=add
		在其他网站里设置网站外连接
		搜索引擎会和DNS服务商合作,可以快速收录新的网站
	
	通用爬虫并不是万物皆可爬的,它需要遵守规则:Robots协议
		协议会指明通用爬虫可以爬取网页的权限
		Robots.txt只是1个建议,并不是所有爬虫都遵守,一般只有大型的搜索引擎才会遵守
	
	通用爬虫工作流程:
		爬取网页
		存储数据
		内容处理
		提供检索/排名服务
	
	搜索引擎排名SEO:
		PageRank值:根据网站的流量(点击量,浏览值,人气)统计,流量越高,网站越值钱,排名越靠前
		竞价排名:谁钱多谁排名靠前
		
	通用爬虫的缺点
		只能提供和文本相关的内容(html,word,pdf)等,但是不能提供多媒体(音乐,图片,视频)和二进制文件(程序,脚本)等
		提供结果千篇一律,不能针对不同人群提供不同搜索结果
		不能理解人类语义上的检索
	
聚集网络爬虫
	概念:爬虫程序员写的针对某种内容的爬虫
	特点:面向主题爬虫,面向需求爬虫,会针对某种特定的内容去爬取信息,而且会保证信息和需求尽可能相关。
	
增量网络爬虫
深层网络爬虫

二、Python2中开发爬虫(了解)

urllib2库的基本使用

所谓网页抓取,就是把URL地址中指定的网络资源从网络流中读取出来,保存到本地。 在Python中有很多库可以用来抓取网页,我们先学习urllib2。

urllib2 是 Python2.7 自带的模块(不需要下载,导入即可使用)
urllib2 官方文档:https://docs.python.org/2/library/urllib2.html
urllib2 源码:https://hg.python.org/cpython/file/2.7/Lib/urllib2.py

urllib2 在 python3.x 中被改为 urllib.request
示例: 使用urllib2抓取百度网页 ( 第一个爬虫程序 )
#!C:\Python36\python.exe
# -*- coding:utf-8 -*-

import urllib2

# url, 统一资源定位符
# data=None,默认为None为get请求,否则设置了data则是post请求
# timeout=超时时间
url = "http://www.baidu.com"
response = urllib2.urlopen(url)
print response  # socket._fileobject object, _fileobject文件对象

# python的文件操作
# print response.read()  # 返回所有内容,字符串
# print response.readline()  # 按行返回

# 读取所有行
# while True:
#     if not response.readline():
#         break
#     print response.readline()

print response.readlines()  # 返回所有行,列表

第一个反反爬

User-Agent
有一些网站不喜欢被爬虫程序访问,所以会检测连接对象,如果是爬虫程序,也就是非人点击访问,它就会不让你继续访问,所以为了要让程序可以正常运行,需要隐藏自己的爬虫程序的身份。此时,我们就可以通过设置User Agent的来达到隐藏身份的目的,User Agent的中文名为用户代理,简称UA。

User Agent存放于Headers中,服务器就是通过查看Headers中的User Agent来判断是谁在访问。在Python中,如果不设置User Agent,程序将使用默认的参数,那么这个User Agent就会有Python的字样,如果服务器检查User Agent,那么没有设置User Agent的Python程序将无法正常访问网站。

常用消息头(详解http请求消息头)
    Accept:text/html,image/*	 (告诉服务器,浏览器可以接受文本,网页图片)
    Accept-Charaset:ISO-8859-1 	 [接受字符编码:iso-8859-1]
    Accept-Encoding:gzip,compress	[可以接受  gzip,compress压缩后数据]
    Accept-Language:zh-cn	[浏览器支持的语言]   
    Host:localhost:8080		[浏览器要找的主机]
    Referer:http://localhost:8080/test/abc.html		[告诉服务器我来自哪里,常用于防止下载,盗链]
    User-Agent:Mozilla/4.0(Com...)		[告诉服务器我的浏览器内核]
    Cookie:	[会话]
    Connection:close/Keep-Alive 	[保持链接,发完数据后,我不关闭链接]
    Date:	[浏览器发送数据的请求时间]

# 设置请求头的User-Agent
header = {
	"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36"
}
# 构造一个请求对象发送请求,伪装浏览器访问
request = urllib2.Request(url, headers=header) 
添加更多的Header信息
在 HTTP Request 中加入特定的 Header,来构造一个完整的HTTP请求消息。

可以通过调用Request.add_header() 添加/修改一个特定的header 也可以通过调用Request.get_header()来查看已有的header。

添加一个特定的header
request.add_header("Connection", "keep-alive") # 一直活着

print request.get_header("User-agent")  # 用户代理, 首字母大写,其他小写
print request.get_full_url() # 访问的网页链接
print request.get_host() # 服务器域名
print request.get_method() # get或post
print request.get_type() # http/https/ftp

response = urllib2.urlopen(request)
print response.code # 状态码200, 404,500
print response.read() # 获取内容

data = response.read().decode("utf-8")  # 根据网页编码格式进行解码,常见编码:utf-8, gbk, gb2312...
print response.code # 响应状态码

url编码:urllib.urlencode()
我们都知道Http协议中参数的传输是"key=value"这种简直对形式的,如果要传多个参数就需要用“&”符号对键值对进行分割。如"?name1=value1&name2=value2",这样在服务端在收到这种字符串的时候,会用“&”分割出每一个参数,然后再用“=”来分割出参数值。

urllib 和urllib2 区别:
	urllib 和 urllib2 都是接受URL请求的相关模块,但是提供了不同的功能。两个最显著的不同如下:
	urllib 仅可以接受URL,不能创建 设置了headers 的Request 类实例;
	但是 urllib 提供 urlencode 方法用来GET查询字符串的产生,而 urllib2 则没有。(这是 urllib 和 urllib2 经常一起使用的主要原因)
	编码工作使用urllib的urlencode()函数,帮我们将key:value这样的键值对转换成"key=value"这样的字符串,解码工作可以使用urllib的unquote()函数。(注意,不是urllib2.urlencode())

urllib.urlencode(keyWord) # url编码
urllib.unquote(kw) # 解码
示例: 模拟百度搜索
#!C:\Python36\python.exe
# -*- coding:utf-8 -*-

import urllib2
import urllib

# 模拟百度搜索
def baiduAPI(params):
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36"
    }

    url = "https://www.baidu.com/s?" + params
    request = urllib2.Request(url, headers=headers)
    response = urllib2.urlopen(request)
    return response.read()

if __name__ == "__main__":
    kw = raw_input("请输入你想查找的内容:")

    wd = {"wd": kw, 'ie': 'utf-8'}
    params = urllib.urlencode(wd)  # url编码:将字典 转换成 参数字符串
    # print wd  # 'wd=aa&ie=utf-8'

    content = baiduAPI(params)
    print content

三、Python3中开发爬虫

示例: urllib.request爬取百度
import urllib
from urllib import request

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36"
}

# 创建请求对象
req = urllib.request.Request("http://www.baidu.com", headers=headers)

response = urllib.request.urlopen(req)
print(response.info())  # 响应信息
print(response.read())  # 二进制
print(response.read().decode('utf-8'))  # 字符串
示例:模拟百度搜索
import urllib.request
import urllib.parse

# 模拟百度搜索
def baiduAPI(params):

    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36"
    }

    url = "https://www.baidu.com/s?" + params
    req = urllib.request.Request(url, headers=headers)
    response = urllib.request.urlopen(req)
    return response.read().decode('utf-8')

if __name__ == "__main__":
    kw = input("请输入你要查找的内容:")
    wd = {"wd": kw}
    params = urllib.parse.urlencode(wd)
    # print(params)  # 'wd=aa'

    response = baiduAPI(params)
    print(response)
示例: 爬取前程无忧岗位数量
import urllib
from urllib import request
import re
import json

headers = {
    "Cookie":"",
    "User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36"
}

# 前程无忧职位网址
url = "https://search.51job.com/list/000000,000000,0000,00,9,99,python,2,1.html?lang=c&stype=&postchannel=0000&workyear=99&cotype=99°reefrom=99&jobterm=99&companysize=99&providesalary=99&lonlat=0%2C0&radius=-1&ord_field=0&confirmdate=9&fromType=&dibiaoid=0&address=&line=&specialarea=00&from=&welfare="

# 开始爬取
req = urllib.request.Request(url, headers=headers)
response = urllib.request.urlopen(req)

html = response.read().decode('gbk')  # HTML源码

re_soup = re.search(r'window.__SEARCH_RESULT__ =(.*?)', html)  # 正则匹配方法得到岗位信息所在位置
json_data = json.loads(re_soup.group(1))
if re_soup != None:
    json_data = json.loads(re_soup.group(1))
    for items in json_data["engine_jds"]:
        jobid = items['jobid']
        print(jobid)
        job_name = items["job_name"]
        company_name = items["company_name"]
        company_type = items['companytype_text']  # 公司类型
        company_size = items['companysize_text']  # 公司规模
        company_ind = items['companyind_text']  # 公司属性
        degreefrom = items['degreefrom']
        workyear = items['workyear']
        jobwelf = items["jobwelf"]
        providesalary_text = items["providesalary_text"]  # 薪资
        workarea = items['workarea']
        workarea_text = items['workarea_text']  # 城市
        issuedate = items['issuedate']  # 发布日期
        attribute_text = items['attribute_text']
        job_href = items['job_href']  # 职位链接
        print(job_href)

抓取ajax数据

示例:抓取豆瓣电影
import urllib
from urllib import request
import json

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36"
}

url = "https://movie.douban.com/j/new_search_subjects?sort=T&range=0,10&tags=&start=0"

req = urllib.request.Request(url, headers=headers)
response = urllib.request.urlopen(req)
content = response.read().decode()  # json数据

data = json.loads(content)
movie_list = data.get('data')

for movie in movie_list:
    title = movie.get('title')
    casts = movie.get('casts')
    print(title, casts)
    
练习: 抓取阿里招聘信息并保存到本地文件
# 抓取阿里招聘信息前5页数据,将每个岗位的信息一行行保存到ali.txt文件中;
# 岗位信息包括:学历degree,部门departmentName,岗位要求description,
#		      类型firstCategory,要求workExperience

url = "https://job.alibaba.com/zhaopin/socialPositionList/doList.json"
for i in range(1, 6):
    params = {
        'pageSize': 10,
        't': '0.15338906034674604',
        'pageIndex': i
    }

下载文件

# 参数1: 需要下载的url
# 参数2: 需要写入的文件路径
request.urlretrieve("http://www.baidu.com", r"baidu.html")
request.urlcleanup()  # 清除缓存

# 下载图片
request.urlretrieve("https://www.baidu.com/img/bd_logo1.png", r"baidu.png")
request.urlcleanup()  # 清除缓存

Handler处理器 和 自定义Opener (了解)

opener是 urllib2.OpenerDirector 的实例,我们之前一直都在使用的urlopen,它是一个特殊的opener(也就是模块帮我们构建好的)。

但是基本的urlopen()方法不支持代理IP、cookie等其他的HTTP/HTTPS高级功能。所以要支持这些功能:
1、使用相关的Handler处理器来创建特定功能的处理器对象;
2、然后通过urllib.request.build_opener()方法使用这些处理器对象,创建自定义opener对象;
3、使用自定义的opener对象,调用open()方法发送请求。

如果程序里所有的请求都使用自定义的opener,可以使用urllib2.install_opener()将自定义的 opener 对象 定义为 全局opener,表示如果之后凡是调用urlopen,都将使用这个opener(根据自己的需求来选择)

简单的自定义opener()

import urllib
from urllib import request

# 构建一个HTTPHandler 处理器对象,支持处理HTTP请求
handler = urllib.request.HTTPHandler()  # http

# 构建一个HTTPHandler 处理器对象,支持处理HTTPS请求
# handlers = urllib.request.HTTPSHandler()  # 处理https的处理器

# 调用urllib2.build_opener()方法,创建支持处理HTTP请求的opener对象
opener = urllib.request.build_opener(handler)

# 构建 Request请求
req = urllib.request.Request("http://www.baidu.com", headers=headers)

# 调用自定义opener对象的open()方法,发送request请求
response = opener.open(req)

# 获取服务器响应内容
print(response.read())

Cookie

Cookie 是指某些网站服务器为了辨别用户身份和进行会话跟踪,而储存在用户浏览器上的文本文件,Cookie可以保持登录信息到用户下次与服务器的会话。

Cookie原理
HTTP是无状态的协议, 为了保持连接状态, 引入了Cookie机制 Cookie是http消息头中的一种属性,包括:
Cookie名字(Name)
Cookie的值(Value)
Cookie的过期时间(Expires/Max-Age)
Cookie作用路径(Path)
Cookie所在域名(Domain),
使用Cookie进行安全连接(Secure)。

前两个参数是Cookie应用的必要条件,另外,还包括Cookie大小(Size,不同浏览器对Cookie个数及大小限制是有差异的)。

Cookie由变量名和值组成,根据 Netscape公司的规定,Cookie格式如下:
Set-Cookie: NAME=VALUE;Expires=DATE;Path=PATH;Domain=DOMAIN_NAME;SECURE

Cookie应用

Cookies在爬虫方面最典型的应用是判定注册用户是否已经登录网站,用户可能会得到提示,是否在下一次进入此网站时保留用户信息以便简化登录手续。

cookielib库 和 HTTPCookieProcessor处理器
在Python处理Cookie,一般是通过cookielib模块和 urllib2模块的HTTPCookieProcessor处理器类一起使用。

cookielib模块:主要作用是提供用于存储cookie的对象

HTTPCookieProcessor处理器:主要作用是处理这些cookie对象,并构建handler对象。

cookielib 库
该模块主要的对象有CookieJar、FileCookieJar、MozillaCookieJar、LWPCookieJar。

CookieJar:管理HTTP cookie值、存储HTTP请求生成的cookie、向传出的HTTP请求添加cookie的对象。整个cookie都存储在内存中,对CookieJar实例进行垃圾回收后cookie也将丢失。

FileCookieJar (filename,delayload=None,policy=None):从CookieJar派生而来,用来创建FileCookieJar实例,检索cookie信息并将cookie存储到文件中。filename是存储cookie的文件名。delayload为True时支持延迟访问访问文件,即只有在需要时才读取文件或在文件中存储数据。

MozillaCookieJar (filename,delayload=None,policy=None):从FileCookieJar派生而来,创建与Mozilla浏览器 cookies.txt兼容的FileCookieJar实例。

LWPCookieJar (filename,delayload=None,policy=None):从FileCookieJar派生而来,创建与libwww-perl标准的 Set-Cookie3 文件格式兼容的FileCookieJar实例。

其实大多数情况下,我们只用CookieJar(),如果需要和本地文件交互,就用 MozillaCookjar() 或 LWPCookieJar()

Cookie案例:

1.获取Cookie
import urllib.request
from http import cookiejar  # python3
# import cookiejar  # python2

# 创建一个对象存储cookie
cookies = cookiejar.LWPCookieJar()
# cookie处理器, 提取cookie
cookie_handler = urllib.request.HTTPCookieProcessor(cookies)
# 创建打开器, 处理cookie
opener = urllib.request.build_opener(cookie_handler)

# 使用opener打开url
response = opener.open("http://www.baidu.com/")
# 得到cookies
print(cookies)

  1. 下载cookie
import urllib.request
from http import cookiejar

filename = "baiducookie.txt"  # 用于保存cookie
# 管理cookie的对象
cookies = cookiejar.LWPCookieJar(filename=filename)
# 创建cookie处理器
cookie_handler = urllib.request.HTTPCookieProcessor(cookies)
# 创建打开器
opener = urllib.request.build_opener(cookie_handler)

# 添加UA,并打开百度,下载cookie
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36"
}

req = urllib.request.Request("http://www.baidu.com", headers=headers)

# 打开
response = opener.open(req)

# 保存, 忽略错误
cookies.save(ignore_discard=True, ignore_expires=True)

  1. 使用下载的cookie
import urllib.request
from http import cookiejar

filename = "baiducookie.txt"
cookies = cookiejar.LWPCookieJar()

# 使用cookie
cookies.load(filename)

cookie_handler = urllib.request.HTTPCookieProcessor(cookies)
opener = urllib.request.build_opener(cookie_handler)

# 添加UA,并打开百度
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36"
}

req = urllib.request.Request("http://www.baidu.com", headers=headers)
response = opener.open(req)

HTTP代理神器Fiddler / Charles青花瓷

Fiddler是一款强大Web调试工具,它能记录所有客户端和服务器的HTTP请求。 Fiddler启动的时候,默认IE的代理设为了127.0.0.1:8888,而其他浏览器是需要手动设置。

请求 (Request) 部分详解

Headers —— 显示客户端发送到服务器的 HTTP 请求的 header,显示为一个分级视图,包含了 Web 客户端信息、Cookie、传输状态等。
Textview —— 显示 POST 请求的 body 部分为文本。
WebForms —— 显示请求的 GET 参数 和 POST body 内容。
HexView —— 用十六进制数据显示请求。
Auth —— 显示响应 header 中的 Proxy-Authorization(代理身份验证) 和 Authorization(授权) 信息.
Raw —— 将整个请求显示为纯文本。
JSON - 显示JSON格式文件。
XML —— 如果请求的 body 是 XML 格式,就是用分级的 XML 树来显示它。

响应 (Response) 部分详解

Transformer —— 显示响应的编码信息。
Headers —— 用分级视图显示响应的 header。
TextView —— 使用文本显示相应的 body。
ImageVies —— 如果请求是图片资源,显示响应的图片。
HexView —— 用十六进制数据显示响应。
WebView —— 响应在 Web 浏览器中的预览效果。
Auth —— 显示响应 header 中的 Proxy-Authorization(代理身份验证) 和 Authorization(授权) 信息。
Caching —— 显示此请求的缓存信息。
Privacy —— 显示此请求的私密 (P3P) 信息。
Raw —— 将整个响应显示为纯文本。
JSON - 显示JSON格式文件。
XML —— 如果响应的 body 是 XML 格式,就是用分级的 XML 树来显示它 。

ProxyHandler处理器(代理设置)

使用代理IP,这是爬虫/反爬虫的第二大招,通常也是最好用的。

很多网站会检测某一段时间某个IP的访问次数(通过流量统计,系统日志等),如果访问次数多的不像正常人,它会禁止这个IP的访问。

所以我们可以设置一些代理服务器,每隔一段时间换一个代理IP,就算IP被禁止,依然可以换个IP继续爬取。

免费的开放代理获取基本没有成本,我们可以在一些代理网站上收集这些免费代理,测试后如果可以用,就把它收集起来用在爬虫上面。

免费短期代理网站举例:(免费代理不稳定,可用率低)
    西刺免费代理IP
    快代理免费代理
    Proxy360代理
    全网代理IP

收费代理:
    芝麻代理,蘑菇代理,快代理等..

import urllib.request
import random

# 假设此时有一已经格式化好的ip代理地址proxies
# 可访问西刺代理获取免费代理ip:http://www.xicidaili.com/

# ip代理
iplist = [
    "http://183.159.84.198:18118",
    "http://183.159.92.206:18118",
    "http://119.179.209.43:61234",
    "http://183.159.82.181:18118"
]

# ua
UserAngentList=[
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; Touch; rv:11.0) like Gecko",
    "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1",
    "Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Mobile Safari/537.36"
]

url = 'https://blog.csdn.net'

for i in range(3):
    headers = { "User-Agent": random.choice(UserAngentList)}
    proxy = {"http": random.choice(iplist)}
    
    try:
    	proxy_handler = urllib.request.ProxyHandler(proxy)
		opener = urllib.request.build_opener(proxy_handler)
		req = urllib.request.Request(url, headers=headers)
		response = opener.open(req)  # 使用代理
		print(response.code)

    except:
        print('失败')
    else:
        print('成功')

HTTP响应状态码参考

1xx:信息
100 Continue
	服务器仅接收到部分请求,但是一旦服务器并没有拒绝该请求,客户端应该继续发送其余的请求。
101 Switching Protocols
	服务器转换协议:服务器将遵从客户的请求转换到另外一种协议。


2xx:成功

200 OK
	请求成功(其后是对GET和POST请求的应答文档)
201 Created
	请求被创建完成,同时新的资源被创建。
202 Accepted
	供处理的请求已被接受,但是处理未完成。
203 Non-authoritative Information
	文档已经正常地返回,但一些应答头可能不正确,因为使用的是文档的拷贝。
204 No Content
	没有新文档。浏览器应该继续显示原来的文档。如果用户定期地刷新页面,而Servlet可以确定用户文档足够新,这个状态代码是很有用的。
205 Reset Content
	没有新文档。但浏览器应该重置它所显示的内容。用来强制浏览器清除表单输入内容。
206 Partial Content
	客户发送了一个带有Range头的GET请求,服务器完成了它。


3xx:重定向

300 Multiple Choices
	多重选择。链接列表。用户可以选择某链接到达目的地。最多允许五个地址。
301 Moved Permanently
	所请求的页面已经转移至新的url。
302 Moved Temporarily
	所请求的页面已经临时转移至新的url。
303 See Other
	所请求的页面可在别的url下被找到。
304 Not Modified
	未按预期修改文档。客户端有缓冲的文档并发出了一个条件性的请求(一般是提供If-Modified-Since头表示客户只想比指定日期更新的文档)。服务器告诉客户,原来缓冲的文档还可以继续使用。
305 Use Proxy
	客户请求的文档应该通过Location头所指明的代理服务器提取。
306 Unused
	此代码被用于前一版本。目前已不再使用,但是代码依然被保留。
307 Temporary Redirect
	被请求的页面已经临时移至新的url。


4xx:客户端错误

400 Bad Request
	服务器未能理解请求。
401 Unauthorized
	被请求的页面需要用户名和密码。
401.1
	登录失败。
401.2
	服务器配置导致登录失败。
401.3
	由于 ACL 对资源的限制而未获得授权。
401.4
	筛选器授权失败。
401.5
	ISAPI/CGI 应用程序授权失败。
401.7
	访问被 Web 服务器上的 URL 授权策略拒绝。这个错误代码为 IIS 6.0 所专用。
402 Payment Required
	此代码尚无法使用。
403 Forbidden
	对被请求页面的访问被禁止。
403.1
	执行访问被禁止。
403.2
	读访问被禁止。
403.3
	写访问被禁止。
403.4
	要求 SSL。
403.5
	要求 SSL 128403.6
	IP 地址被拒绝。
403.7
	要求客户端证书。
403.8
	站点访问被拒绝。
403.9
	用户数过多。
403.10
	配置无效。
403.11
	密码更改。
403.12
	拒绝访问映射表。
403.13
	客户端证书被吊销。
403.14
	拒绝目录列表。
403.15
	超出客户端访问许可。
403.16
	客户端证书不受信任或无效。
403.17
	客户端证书已过期或尚未生效。
403.18
	在当前的应用程序池中不能执行所请求的 URL。这个错误代码为 IIS 6.0 所专用。
403.19
	不能为这个应用程序池中的客户端执行 CGI。这个错误代码为 IIS 6.0 所专用。
403.20
	Passport 登录失败。这个错误代码为 IIS 6.0 所专用。
404 Not Found
	服务器无法找到被请求的页面。
404.0
	没有找到文件或目录。
404.1
	无法在所请求的端口上访问 Web 站点。
404.2
	Web 服务扩展锁定策略阻止本请求。
404.3
	MIME 映射策略阻止本请求。
405 Method Not Allowed
	请求中指定的方法不被允许。
406 Not Acceptable
	服务器生成的响应无法被客户端所接受。
407 Proxy Authentication Required
	用户必须首先使用代理服务器进行验证,这样请求才会被处理。
408 Request Timeout
	请求超出了服务器的等待时间。
409 Conflict
	由于冲突,请求无法被完成。
410 Gone
	被请求的页面不可用。
411 Length Required
	"Content-Length" 未被定义。如果无此内容,服务器不会接受请求。
412 Precondition Failed
	请求中的前提条件被服务器评估为失败。
413 Request Entity Too Large
	由于所请求的实体的太大,服务器不会接受请求。
414 Request-url Too Long
	由于url太长,服务器不会接受请求。当post请求被转换为带有很长的查询信息的get请求时,就会发生这种情况。
415 Unsupported Media Type
	由于媒介类型不被支持,服务器不会接受请求。
416 Requested Range Not Satisfiable
	服务器不能满足客户在请求中指定的Range头。
417 Expectation Failed
	执行失败。
423
	锁定的错误。


5xx:服务器错误

500 Internal Server Error
	请求未完成。服务器遇到不可预知的情况。
500.12
	应用程序正忙于在 Web 服务器上重新启动。
500.13
	Web 服务器太忙。
500.15
	不允许直接请求 Global.asa。
500.16
	UNC 授权凭据不正确。这个错误代码为 IIS 6.0 所专用。
500.18
	URL 授权存储不能打开。这个错误代码为 IIS 6.0 所专用。
500.100
	内部 ASP 错误。
501 Not Implemented
	请求未完成。服务器不支持所请求的功能。
502 Bad Gateway
	请求未完成。服务器从上游服务器收到一个无效的响应。
502.1
	CGI 应用程序超时。 ·
502.2
	CGI 应用程序出错。
503 Service Unavailable
	请求未完成。服务器临时过载或当机。
504 Gateway Timeout
	网关超时。
505 HTTP Version Not Supported
	服务器不支持请求中指明的HTTP协议版本

你可能感兴趣的:(Python爬虫,python)