【python】python爬虫

爬虫基础

HTTP协议
HTTP是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。

HTTP是基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)
通过TCP/IP通信协议来在Client和Server之间建座桥
HTTP请求和响应就在这座桥上传递.
请求和响应中包含着相关信息.
HTTP请求流程
一次http请求的基本流程是,有客户端向服务端发起一次请求(request), 而服务器在接收到以后返回给客户端一个响应(response)。所以一次完整的http请求包含请求和响应两部分。

提供http服务的服务器, 会默认监听80端口, 也就是服务器上的服务端程序监听的端口为80端口
HTTPS协议
HTTPS(全称:Hyper Text Transfer Protocol over Secure Socket Layer 或 Hypertext Transfer Protocol Secure,超文本传输安全协议),是以安全为目标的HTTP通道,简单讲是HTTP的安全版

http协议是基于tcp/ip协议的,而https是在http协议的基础之上,再加了一层SSL/TLS协议,数据在传输过程中是加密的。

HTTPS协议的默认端口是443

URL
发送http请求时,通过url对网络资源进行定位。
在这里插入图片描述
HTTP请求报文
在这里插入图片描述
在这里插入图片描述
HTTP请求方法
常用请求方法
在这里插入图片描述
根据http标准,http请求可以使用多种请求方法。
在这里插入图片描述
HTTP请求头
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
HTTP请求正文
请求正文通常是使用POST方法进行发送的数据,GET方法是没有请求正文的。

请求正文跟上面的消息报头由一个空行隔开。
HTTP响应
HTTP响应也由四个部分组成,分别是:状态行、消息报头、空行和响应正文。
在这里插入图片描述
在这里插入图片描述
HTTP响应状态码
当客户端向服务端发起一次请求后,服务端在返回的响应头中会包含一个HTTP状态码。

HTTP的状态码是由三位数字来表示的,由第一位数字来表示状态码的类型,一般来说有五种类型:
在这里插入图片描述
HTTP响应报头
在这里插入图片描述

HTTP协议的特点
HTTP三点注意事项:

  • HTTP是无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。

  • HTTP是媒体独立的:这意味着,只要客户端和服务器知道如何处理的数据内容,任何类型的数据都可以通过HTTP发送。客户端以及服务器指定使用适合的MIME-type内容类型。

  • HTTP是无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。

Cookie
HTTP是无状态的,协议本身不涉及保存访问记录, 也就是请求和响应过程中不保存相关记录信息, 这样的特性会造成两个现状:
1. 基于HTTP实现的应用在数据交互时, 交互速度比较快
2. 由于不记录信息, 服务器无法区分访问自己的客户端.
总结: 用户的个人信息一般会放在Cookie中(这些信息可以是账号和密码, 也可以是其他东西), 用来在访问特定页面时(如访问个人中心页面)包含在请求中, 发给服务器验证.但是Cookie若被骇客盗用, 那么骇客也能去访问用户的个人中心页面, 就像上面的第三次交互.
Session
在一个客户从打开浏览器到关闭浏览器这个期间内,发起的所有请求都可以被识别为同一个用户。而实现的方式则是,在一个客户打开浏览器开始访问网站的时候,服务器会生成一个SessionID值并和在服务器中的用户信息进行绑定, 客户端获取到SessionID后以Cookie的方式保存, 这个ID每次的访问都会带上,而服务器会识别这个SessionID由此来实现客户端的状态识别。因此session是基于cookie的

Session与Cookie相反,Session是存储在服务器上的数据,对客户端传上来的SessionID来进行判定,所以相对于Cookie,Session的安全性更高。

一般SessionID会在浏览器被关闭时丢弃,或者服务器会验证Session的活跃程度,例如30分钟某一个SessionID都没有活跃,那么也会被识别为失效。

数据采集

—urllib库

url请求模块

from urllib import request

方法:
request.Request(url)
request模块主要负责构造和发起网络请求,并在其中添加Headers,Proxy等。
利用它可以模拟浏览器的请求发起过程。
request.urlopen(url,data=None,timeout)
urlopen默认会发送get请求,当传入data参数时,则会发起POST请求。data参数是字节类型、者类文件对象或可迭代对象。

request方法和response对象方法的使用

from urllib import request

#构造请求信息
req=request.Request('http://www.baidu.com')

#发送请求 返回响应信息
response=request.urlopen(req)

#常用response对象的方法
print(response.read())#获取响应数据

print(response.info())#获取响应信息

print(response.geturl())#获取访问的url

print(response.getcode())#获取http状态码

请求头添加

from urllib import request
headers={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.26 Safari/537.36 Core/1.63.6821.400 QQBrowser/10.3.3040.400"}
#构造请求信息
req=request.Request('http://www.baidu.com',headers=headers)

#发送请求 返回响应信息
response=request.urlopen(req)


#常用response对象的方法
print(response.read().decode())#获取响应数据

操作cookie

from urllib import request
from http import cookiejar
#创建一个cookie对象
cookie=cookiejar.CookieJar()

#创建一个cookie处理器
cookies=request.HTTPCookieProcessor(cookie)

#以它为参数 创建一个opener对象
opener=request.build_opener(cookies)

#发送请求 获取响应
res=opener.open('http://www.baidu.com')

#获取响应数据
print(cookies.cookiejar)

设置代理ip

from urllib import request
#设置爬取网站地址
url='http://httpbin.org/get'
#代理地址
proxy={'http':'27.208.80.66:8060'}
#代理案处理器
proxies=request.ProxyHandler(proxy)
#创建opener对象
opener=request.build_opener(proxies)

#发送请求 获取响应
response=opener.open(url)
#打印响应信息
print(response.read().decode())

url编码模块

 from urllib import parse

方法:
对特殊字符进行编码parse.quote(字符串)
对特殊字符进行解码parse.unquote(字符串)
url编码表单字典信息parse.urlencode(字典)
解码表单字典信息parse.parse_qs(字典url编码的字符串)

url异常报错模块

from urllib import error

error模块主要负责处理异常,如果请求出现错误,我们可以用error模块进行处理
主要包含URLError和HTTPError

URLError的报错使用

from urllib import error
try:
    pass#爬虫代码
except error.URLError as e:
    print(e)

HTTPError的报错使用

from urllib import error
try:
    pass#爬虫代码
except error.HTTPError as e:
    print(e.code)#获取http状态码
    print(e.reason)#获取错误原因
    print(e.headers)#获取响应的报头

urllib爬取实例

from urllib import request
from urllib import parse
#添加请求头
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.26 Safari/537.36 Core/1.63.6821.400 QQBrowser/10.3.3040.400"}
#添加表单
formdata={"i": "快乐",
"from":" AUTO",
"to":"AUTO",
"smartresult":"dict",
"client":" fanyideskweb",
"salt":"15587539525925",
"sign":"981e5ff6edbf915b9e0238b82ce10bf5",
"ts":"1558753952592",
"bv":"64bf5afb3cca58e10e1392ed7a581832",
"doctype":"json",
"version":"2.1",
"keyfrom":"fanyi.web",
"action":"FY_BY_CLICKBUTTION"}
#url编码和字节编码表单
post_formdata=parse.urlencode(formdata).encode()
url='http://fanyi.youdao.com/translate?'
#设置代理ip
proxy={'http':'27.208.80.66:8060'}
#代理处理器
proxies=request.ProxyHandler(proxy)
#创建opener对象
opener=request.build_opener(proxies)
#构造请求信息
req=request.Request(url,data=post_formdata,headers=headers)
#发送请求 获取响应
response=opener.open(req)
#打印响应信息
print(response.read().decode())

—urllib3库

import urllib3

1.实例化PoolManager对象
http=urllib3.PoolManager().
2.发送request请求
response=http.request(请求方式,url,[field])
GET,HEAD,DELETE请求,可以通过提供字典类型的参数fields来添加查询参数
在这里插入图片描述
对于POST和PUT请求,如果需要查询参数,需要通过url编码将参数编码成正确格式然后拼接到url中
在这里插入图片描述

3.response对象的方法
获取http状态码response.status()
获取响应数据response.data()
获取响应头信息response.headers()

添加请求头

import urllib3
import json
headers = {
     "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.26 Safari/537.36 Core/1.63.6821.400 QQBrowser/10.3.3040.400"}
http=urllib3.PoolManager()
response=http.request('GET','http://httpbin.org/get',headers=headers)
#json数据转为字典数据
print(json.loads(response.data.decode()))

设置代理ip

import urllib3
import json
proxy=urllib3.ProxyManager('http://119.190.150.181:8060')
response=proxy.request('GET','http://httpbin.org/get')
print(json.loads(response.data.decode()))

提交表单
对于put和post请求,需要提供字典类型的参数field来传递form表单数据。

import urllib3
import json
proxy=urllib3.ProxyManager('http://119.190.150.181:8060')
response=proxy.request('POST','http://httpbin.org/post',fields={'name':'jack'})
print(json.loads(response.data.decode()))

发送json数据
当我们需要发送json数据时,我们需要在request中传入编码后的二进制数据类型的body参数,并制定Content-Type的请求头

import urllib3
import json
encode_data=json.dumps({'name':'jack'})#字典数据转json数据
proxy=urllib3.ProxyManager('http://119.190.150.181:8060')
response=proxy.request('POST','http://httpbin.org/post',headers={'Content-Type':'application/json'},body=encode_data)
print(json.loads(response.data.decode()))

二进制数据分割传输

—requests库

官方中文文档:https://2.python-requests.org//zh_CN/latest/
发送请求的方法

请求方法说明
requests.request(method,url)获取HTML网页的通用方法
requests.get(url)获取HTML网页的主要方法,对应HTTP的GET
requests.post(url)向HTML网页提交POST请求方法,对应HTTP的POST
requests.put(url)向HTML网页提交PUT请求的方法,对应HTTP的RUT
requests.delete(url)向HTML页面提交删除请求,对应HTTP的DELETE
requests.head(url)获取HTML网页头的信息方法,对应HTTP的HEAD
requests.options(url)发送“探测”请求以确定某个目标地址的请求具有怎样的约束
requests.patch(url)向HTML网页提交局部修改请求,对应于HTTP的PATCH

请求方法的参数

请求方法的参数说明
headers(字典类型)请求头设置
proxies(字典类型)代理设置
params(字典类型)传递URL参数
data(字典类型)提交表单数据
json(字典类型)提交json数据
cookies(字典类型)cookie设置
timeout(数值类型)设置访问超时时间(单位为秒)
allow_redirects(布尔类型)重定向设置(参数值True为允许,False为禁止)
verify(布尔类型)证书验证设置(参数值True为打开,False为关闭)

解除verify证书验证关闭后的警报:

import urllib3
urllib3.disable_warnings()

获取响应对象属性

响应对象的属性说明
r.headers获取响应的报头
r.cookies获取服务器返回的cookie
r.status_codeHTTP请求的返回状态
r.url获取响应内容的url
r.encoding设置响应数据的编码方式
r.contentHTTP响应内容的二进制形式
r.textHTTP响应内容的字符串形式(url对应的html页面内容)
r.json()HTTP响应内容的json数据转换为字典类型

Session对象

#引入urllib3模块
import urllib3
#实例化session对象
s=urllib3.Session()
#发送请求
r=s.get('http://www.baidu.com')

session发送请求格式

s.请求方法(url,各种请求方法的参数)
请求方法:get/post/put/delete/options/head/patch
各种请求方法的参数:headers/proxies/params/data/json/timeout/allow_redirects/verify

session对象的属性

session对象的属性设置说明
s.headers(字典类型)请求头设置
s.proxies(字典类型)代理设置
s.params(字典类型)传递URL参数
s.data(字典类型)提交表单数据
s.json(字典类型)提交json数据
s.cookies(字典类型)cookie设置
s.timeout(数值类型)设置访问超时时间(单位为秒)
s.allow_redirects(布尔类型重定向设置(参数值True为允许,False为禁止)
s.verify(布尔类型)证书验证设置(参数值True为打开,False为关闭)

数据清洗

—BeautifulSoup

官方中文文档:https://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html
安装模块:pip install beautifulsoup4

from bs4 import BeautifulSoup
soup=BeautifulSoup(响应的文本内容)#实例化
BeautifulSoup对象属性和方法说明
soup.标签名获取标签
soup.标签名.name获取标签名
soup.标签名.string获取标签的文字内容
soup.标签名.parent.name获取标签的父标签名
soup.标签名['class']获取标签的类的值
soup.find_all("标签"/ 属性名="值”)根据标签名或属性值查找符合的所有标签
soup.find("标签"/ 属性名="值”)根据标签名或属性值查找所有符合标签的的第一个标签

1.获取所有某个标签的指定属性值

for i in soup.find_all('a'):
     print(i.get("href"))#获取所有a标签的href属性值

—XPath

from lxml import etree
import requests
res=requests.get('www.baidu.com')

#字符串 转换为 html
html=etree.HTML(res.text)

#html 转换为 字符串
html_to_str=etree.tostring(html,encoding='utf-8)

#使用xpath
html.xpath('//title/text()')

选取结点

路径表达式说明
bookstore选取 bookstore 元素的所有子节点
/bookstore选取根元素 bookstore
bookstore/book选取属于 bookstore 的子元素的所有 book 元素
//book选取所有 book 子元素,而不管它们在文档中的位置
bookstore//book选择属于 bookstore 元素的后代的所有 book 元素,而不管它们位于 bookstore 之下的什么位置
//@lang选取名为 lang 的所有属性

谓语

路径表达式说明
/bookstore/book[1]选取属于 bookstore 子元素的第一个 book 元素
/bookstore/book[last()]选取属于 bookstore 子元素的最后一个 book 元素
/bookstore/book[last()-1]选取属于 bookstore 子元素的倒数第二个 book 元素
/bookstore/book[position()< 3]选取最前面的两个属于 bookstore 元素的子元素的 book 元素
//title[@lang]选取所有拥有名为 lang 的属性的 title 元素
//title[@lang=‘eng’]选取所有 title 元素,且这些元素拥有值为 eng 的 lang 属性
/bookstore/book[price>35.00]选取 bookstore 元素的所有 book 元素,且其中的 price 元素的值须大于 35.00
/bookstore/book[price>35.00]/title选取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值须大于 35.00

选取未知结点

路径表达式说明
/bookstore/*选取 bookstore 元素的所有子元素
//*选取文档中的所有元素
//title[@*]选取所有带有属性的 title 元素

选取多个路径

路径表达式说明
//book/title | //book/price选取 book 元素的所有 title 和 price 元素
//title | //price选取文档中的所有 title 和 price 元素
/bookstore/book/title | //price选取属于 bookstore 元素的 book 元素的所有 title 元素,以及文档中所有的 price 元素

—re正则表达式

常用的匹配表达式:https://blog.csdn.net/qq_44647926/article/details/89383250

re中的方法使用方法说明
re.findall(x,y)x:寻找的字符串 y:从y字符串中寻找从整个字符串里面匹配,将所有匹配到的字符以列表形式返回
re.match(x,y)x:寻找的字符串 y:从y字符串中寻找从起始位置开始匹配,若没有匹配到则返回None
re.search(x,y)x:寻找的字符串 y:从y字符串中寻找从整个字符串里面匹配,匹配第一次出现的字符串
re.complie(正则表达式)c=re.compile(正则表达式),c.match(字符串),c.search(字符串),c.findall(字符串)将正则表达式实例化,供match,search,findall方法使用
re.split(x,y)x:分割界限字符串 y:从y字符串中寻找从整个字符串里面匹配,将所有匹配到的字符以列表形式返回
re.finditer(x,y)x:寻找的字符串 y:从y字符串中寻找从整个字符串里面匹配,将所有匹配到的字符以迭代器形式返回

1.match search 方法中需要用group()来返回已经匹配到的字符串span()来返回已经匹配的字符串的下标值
2.匹配换行\n在re方法中传入参数re.S
3.开启对大小写不敏感在re方法中传入参数re.l

元字符说明
代表数量的元字符
*要匹配的前一个字符出现0次或者无限次
+要匹配的前一个字符至少出现1次
?要匹配的前一个字符出现1次或者0次
{n}匹配前一个字符出现n次
{n,}匹配前一个字符至少出现n次
{m,n}匹配前一个字符出现m到n次
匹配边界的元字符
^匹配字符串开头
$匹配字符串结尾
\b匹配一个单词的边界
\B匹配一个单词的非边界
A|B匹配左右任意一个表达式
()将括号里的内容提取出来
.*找最长的匹配 尽可能多的匹配内容
.*?找最短的匹配
匹配通用符
\d匹配数字
\D匹配非数字
\s匹配空白
\S匹配非空白
\w匹配单词字符(a-z, A-Z ,0-9, _)
\W匹配非单词字符
[abcde]匹配时原子表中出现的每个原子都可以匹配到
[^abc]匹配除abc之外的字符
[0-9]匹配一个数字
[a-z]和[A-Z]匹配一个字母
[\u4e00-\u9fa5]匹配一个中文

scrapy框架

scrapy框架

数据存储

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值