Python爬虫一篇就够了


每日一记

Python爬虫思路

1.发送请求获取网站html代码
2.过滤有效信息
3.解析数据
4.处理数据

爬取过程

1.找到网站发起请求
2.分析url并提取
3.分析url并解释网络内容
4.存储数据并获取新url
5.判断是否满足停止条件0

robots协议

决定可以访问的user(允许爬取的user)

http与https

http端口是8080
https加密,SSL层,端口是443

URL与URI

url包括协议类型,主机名/域名,端口号,查找路径,查找参数,锚点
uri是utl请求之前部分

请求方式

get不影响资源/post影响资源

请求头参数

user-agent:浏览器名称
referer:请求源头
cookie:用于判断用户身份

常见响应状态码

200:正常返回
301:永久重定向
404:url错误
418:反爬虫,解决响应
500:服务器错误,bug

请求交互过程

1.客户端浏览器向服务器发送请求
2.网站接收请求处理后返回响应数据
3.浏览器解析源码

开发者工具

element:分析网页结构,获取数据
console:打印输出网站信息
network:查看网络请求
source:所有的源文件(只能查看静态数据)

Session与Cookie原理

【Session】
特点:可长时间保存会话
过程:
1.客户端第一次发送请求时服务器端创建Session对象(生成sessionID)
2.将sessionID存入cookie传回
3.下次发送请求时包含sessionID
【Cookie】
特点:从服务器发送给浏览器后一直保存到关闭浏览器
过程:
1.创建cookie
2.设置存储cookie
3.发送cookie
4.读取cookie

JSON(数据交换语言)

JavaScript ObjectNotation,JS对象标记
数据格式:
1.对象表示为键值对
2.数据用逗号分隔
3.花括号保存对象
4.方括号保存数组
整体上与python的字典相似
例:

json_yuju={'name':'python','address':{'province':'guangdong','city':['guangzhou','huizhou']}}
print(json_yuju['address']['city'][2])               //输出huizhou

Ajax(Web数据交互方式)

Ajax在服务器与浏览器之间使用异步数据传输(可以只请求少量信息)
Ajax技术独立于浏览器与平台
Ajax一般返回JSON(对Ajax地址进行post或get就可以返回JSON数据)
Ajax渲染到html的叫做动态数据
服务器后台生成的是静态数据
html中的在source中没有找到那就是ajax
注意:Ajax需要用户允许JavaScript在浏览器上执行

urllib

py自带的网络请求库
模块:
urllib.request打开并读取url

模拟浏览器发送请求并获取响应结果
data默认为None即Get请求,post请求时要将data以字典形式存储,由字典类型转换成字节类型
转换成的数据类型看网页源代码

【GET】
import urllib.request
url='https......'                           //传入url
response=urllib.request.urlopen(url)        //发送get请求
html=response.read().decode('gbk')          //读取响应并将数据类型转为str
print(html)

【POST】
import urllib.request
url='https......'                           //传入url
data={'a':'A','b':'B','action':'login'}     //从Form Data处查看
response=urllib.request.urlopen(url,data=bytes(urllib.prase.urlencode(data),encoding='utf-8'))
html=response.read().decode('gbk')          //读取响应并将数据类型转为str
print(html)

【通过伪造请求头绕过418】
import urllib.request
url='https......'                           //传入url
header={'User-Agent':'浏览器信息'}
request=urllib.request.Request(url,headers=header)
response=urllib.request.urlopen(request)
html=response.read().decode('utf-8')        //读取响应并将数据类型转为str
print(html)

urllib.error包含提出的异常urllib.request

import urllib.request
import urllib.error
url='目标地址'
try:
    response=urllib.request.urlopen(url)    //尝试链接
expect urllib.error.URLError as e:          //捕获返回信息
    print(e.reason)

urllib.parse解析url

import urllib.parse
a={'A':'内容'}                              //创建键值对
result1=urllib.parse.urlencode(a)           //url编码
result2=urllib.prase.unquote(result1)       //url解码

属性:
code:请求返回的状态码
reason:返回错误的原因
headers:请求返回的响应头信息

urllib.robotparase解析robots.txt文件

IP代理

网站会拒绝同一IP多次访问
命令行中输入ipconfig的IPv4是本地IP
分类:
1.透明代理,知道使用了且知道源IP
2.匿名代理,知道使用了但是不知道源IP
3.高匿代理,都不知道
免费网站
语法:

from urllib.request import build_opener
from urllib.request import ProxyHandler
proxy=ProxyHandler({'协议类型http/https':'IP地址:端口'})
opener=build_opener(proxy)
url='目标地址'
response=opener.open(url)
print(response.read().decode('utf-8'))

使用Cookie

使用步骤:
1.实例化MozillaCookieJar(保存cookie)
2.创建handler对象(cookie的处理器)
3.创建opener对象
4.打开网页发送请求获取响应
5.保存cookie文件
语法:

import urllib.request
from http import cookiejar
filename='cookie.txt'
def get_cookie():                                         //定义获取cookie函数
    cookie=cookiejar.MozillaCookieJar(filename)           //实例化MCJ
    handler=urllib.request.HTTPCookieProcessor(cookie)    //创建handler对象
    opener=urllib.request.build_opener(handler)           //创建opener对象
    url='目标地址'
    response=opener.open(url)                             //发送请求并获取响应
    cookie.save()                                         //保存cookie文件

def use_cookie():                                         //定义获取cookie函数
    cookie=cookiejar.MozillaCookieJar()                   //实例化MCJ
    cookie.load(filename)                                 //加载cookie文件
    print(cookie)

if __name__ = '__main__':
    use_cookie()                                          //读取cookie

requests库(包括上面的功能)

常用方法:requests
requests.request(url)            //构造请求
requests.get(url,params=None)    //Get请求。params可省略,params是请求的参数
requests.post(url,data=None,json=None)
requests.head()                  //获取html头部信息
requests.put()                   //发送Put请求
requests.patch()                 //提交局部修改的请求
requests.delete()                //提交删除请求
params是请求参数

常用属性:
response.status_code             //响应状态码
response.content                 //response对象转为二进制数据
response.text                    //response对象转为字符串数据
response.encoding                //定义response对象编码
response.cookies()               //获取请求后的cookie
response.session()               //获取请求后的session
response.url                     //获取请求网址
response.json()                  //内置JSON解码器
Response.headers                 //以字典对象存储服务器响应头,字典不分大小写

获取二进制数据实例:
import requests
url='目标文件的地址'
response=requests.get(url)
with open('文件名,模式','wb') as file:              //读写文件的操作
    file.write(response.content)
    
常用参数:
r:   以只读方式打开文件。文件的指针将会放在文件的开头。这是**默认模式**。
r+:  打开一个文件用于读写。文件指针将会放在文件的开头。
w:   打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
w+:  打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
a:   打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
a+:  打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。

rb:  以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。
rb+: 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。
wb:  以二进制格式打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
wb+: 以二进制格式打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
ab:  以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
ab+: 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。

file.read([size])        将文件数据作为字符串返回,可选参数size控制读取的字节数
file.readlines([size])   返回文件中行内容的列表,size参数可选
file.write(str)          将字符串写入文件
file.writelines(strings) 将字符串序列写入文件
file.close()             关闭文件
file.closed              表示文件已经被关闭,否则为False
file.mode                Access文件打开时使用的访问模式
file.encoding            文件所使用的编码
file.name                文件名
file.newlines            未读取到行分隔符时为None,只有一种行分隔符时为一个字符串,当文件有多种类型的行结束符时,则为一个包含所有当前所遇到的行结束的列表
file.softspace           为0表示在输出一数据后,要加上一个空格符,1表示不加。这个属性一般程序员用不着,由程序内部使用

XPath解析数据(lxml库)

概述:
小型查询语言,在XML文档中查找信息的语言
优点:
可在XPath中查找信息
支持HTML查找
可通过元素和属性进行导航
XML树形结构和语句与HTML相类似
XPath语法点击此处
代码实现:

import requests
from lxml import etree
url='目标地址'
headers={请求头信息,以键值对形式存储}
response=requests.get(url,headers)
etree=rtree.HTML(response.text)                       //将响应的str类型转换为etree类型
A=etree.xpath('谷歌浏览器中XPath的语句')              //获取内容
B=etree.path('另一个语句')
for A中定位的元素,B中定位的元素 in zip(A,B)           //遍历打包
    print(A中定位的元素, ':' ,B中定位的元素)          //输出

BeautifulSoup解析数据(bs4库)

概述:
能从HTML和XML文件中提取数据的库
语法:

                        【Tag对象】
print(bs.标签)                       //获取标签
print(bs.标签.attrs)                 //获取标签的全部属性
print(bs.标签['属性名'])             //获取属性值
print(bs.标签.text)                  //获取标签的文本内容(不包括注释内的)
print(bs.标签.string)                //获取标签的文本内容(包括注释内的)
                        【CSS选择器】
print(bs.select('ID'))               //ID查找
print(bs.select('classa'))           //classa查找
print(bs.select(标签,属性))          //属性查找
                        【其他功能】
print(bs.find(标签,属性))            //提取首个满足条件的
print(bs.find_all(标签,属性))        //提取所有满足条件的

代码实现:

import requests
from bs4 import BeautifulSoup
url='目标地址'
headers={头文件键值对}
response=requests.get(url,headers)
bs=BeautifulSoup(response.text,'html.parser')               //bs=BeautifulSoup(response.text,'lxml')二选一使用即可
a_list=bs.find_all('标签')
for a in a_list:
    url=a.get('属性')
    if url==None                                              //以None开头的url无用
        continue
    if url.startswich('http') or url.startswich('https')      //保留以http或https开头的url
        print(url)

正则表达式(re库)

概述:
特殊的字符序列,检查字符串是否与某种模式相匹配
正则语法:

.           //匹配任意字符
^           //匹配字符串开头
$           //匹配字符串末尾
*           //匹配前一个元字符0到多次
+           //匹配前一个元字符1到多次
?           //匹配前一个元字符0到1次
{m}         //匹配前一个元字符m次
{m,n}       //匹配前一个元字符m到n次
{m,n}?      //匹配前一个元字符m到n次,并去尽可能少的情况
\\          //对特殊字符转义
[]          //字符集合,匹配其中任意一个字符
|           //或
(...)       //作为一个元组,findall在有组情况下只显示组的内容

特殊序列:

\A          //只在字符串开头匹配
\b          //匹配开头或结尾的空字符串
\B          //匹配不位于开头或结尾的空字符串
\d          //匹配十进制数,[0-9]
\D          //匹配非字符数字字符,[^0-9]
s           //匹配空白字符,[\t\n\r\f\v]
\S          //匹配非空白字符,[^\t\n\r\f\v]
\w          //匹配数字字母下划线,[a-z A-Z 0-9]
\W          //匹配非数字字母下划线,[^a-z A-Z 0-9]
\Z          //只在字符串末尾进行匹配
[\u4e00-\u9fa5]         //中文

正则处理函数:

re.match(pattern,string,flags=0)                  //从字符串开头匹配模式,成功则返回成功的对象,否则返回None
re.search(pattern,string,flags=0)                 //扫描整个字符串返回第一个成功匹配的对象,失败则返回None
re.findall(pattern,string,flags=0)                //获取列表的所有匹配的字符串,以列表形式返回
re.sub(pattern,repl,string,count=0,flags=0)       //用于替换字符串的匹配项,没有匹配项则返回没有匹配的字符串
re.compile(pattern,[,flag])                       //编译正则表达式,生成正则表达式对象,供match和search函数使用

爬取并下载视频示例

import requests
import re
url='目标地址'
headers={请求头}
response=requests.get(url,headers=headers)                            //发送请求
info=re.findall('标签,配合使用正则表达式',response.text)             //正则查找所有符合要求的对象
lst=[]
for item in info:
    lst.append('https:'+item)                                         //将符合条件的对象放入列表中并补全绝对路径
count=0
for item in lst:
    count+=1
    response=requests.get(item.headers=headers)                       //将补全的路径再次请求
    with open('存储路径'+str(count)+'后缀') as file                   //设置下载路径和文件名
        file.write(response.content)                                  //将文件存为二进制
print(下载完毕)

pyquery解析数据(pyquery库)

概述:
是jQuery的Python实现,可以jQuery语法操作解析HTML文档,易用性和解析速度很好
初始化方式:

字符串方式
from pyquery import PyQuery as py
html='html代码'
doc=py(html)      //创建PyQuery对象,将str类型转换为PyQuery类型

url方式
from pyquery import PyQuery
doc=PyQuery(url='地址',encoding='utf-8')

文件
from pyquery import PyQuery
doc=PyQuery(filename='存有html文件的地址')

使用方式:

doc('#main')                             //获取当前节点
doc('#main').children()                  //获取子节点
doc('#main').parent()                    //获取父节点
doc('#main').sinlings()                  //获取兄弟节点
doc('标签')attr('属性')                  //获取属性值
doc('#main').html()                      //获取内容,以html代码形式显示
doc('#main').text()                      //获取内容,以文本显示显示

代码实现:

import requests
from pyquery import PyQuery as py
url=''
headers={}
response=resquests.get(url,headers=headers)   //发送请求
doc=py(response.text)                         //初始化PyQuery对象
A=[x.text for x in doc(h4 a)]                 //从doc中提取h4中的a标签的内容传给x,再显示x的文本部分

总结

requests用于发送和接收请求
四种解析方式是数据的提取
对于爬虫更重要的是提取了数据之后对数据的操作

2023.3.3补档

今日发现一个好用的库叫做URLParser,可以去尝试一下

每日一句

想不清楚一件事,往往因为这件事里有你想逃避的东西。

评论
  目录