Python-爬虫基础总结

爬虫基础总结

一、爬虫

什么是爬虫Spider

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

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

为什么学习爬虫
	百度,谷歌,360搜索, bing搜索, ... 
	私人定制一个搜索引擎,并且可以对搜索引擎的数采集工作原理进行更深层次地理解
	获取更多的数据源,并且这些数据源可以按我们的目的进行采集,去掉很多无关数据
	更好的进行seo(搜索引擎优化)  翻墙:蓝灯, VPN Plus, 搬瓦工

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

Python爬虫的优势

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

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

C/C++: 运行效率和性能几乎最强,但是学习成本非常高,代码成型较慢,能用C/C++写爬虫,说明能力很强,但不是最正确的选择.
    
# SQL: 专门用于关系型数据库的
# Shell: 运维
# JavaScript: 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(缓存,速度快)
	

二、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

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://search.51job.com/list/000000,000000,0000,00,9,99,python,2,1.html?lang=c&stype=&postchannel=0000&workyear=99&cotype=99&degreefrom=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="

抓取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)

下载文件

# 参数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()  # 清除缓存

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

HTTP代理神器Fiddler

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
UserAgentList=[
    "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(UserAgentList)}
    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协议版本

猜你喜欢

转载自blog.csdn.net/Yuyu920716/article/details/113108400