目录
附:爬虫最主要的处理对象就是URL,它根据URL地址取得所需要的文件内容,然后对它 进行进一步的处理。
一,抓取网页的含义和URL基本构成
1,网络爬虫的定义
- 通过网页的链接地址来寻找网页的
- 从网站某一个页面(通常是首页)开始,读取网页的内容,找到在网页中的其它链接地址,然后通过这些链接地址寻找下一个网页,这样一直循环下去,直到把这个网站所有的网页都抓取完为止。
2,浏览网页的过程
-
在地址栏中地址栏输入地址,浏览器作为一个浏览的客户端向服务器发送一次请求,把服务器的文件抓到本地进行解析
-
浏览器的功能是将获取的HTML进行解析,将原始代码转变成我们直接看到的网站页面
3,URI的理解
- Web上每种可用的资源,如 HTML文档、图像、视频片段、程序等都由一个通用资源标志符(Universal Resource Identifier, URI)进行定位。
-
URI通常由三部分组成:
①访问资源的命名机制;
②存放资源的主机名;
③资源自身 的名称,由路径表示。
-
http://www.why.com.cn/myhtml/html1223/ 解析:
①这是一个可以通过HTTP协议访问的资源,
②位于主机 www.webmonkey.com.cn上,
③通过路径“/html/html40”访问。
4,URL的理解
- URL是URI的一个子集。采用URL可以用一种统一的格式来描述各种信息资源,包括文件、服务器的地址和目录等。
-
URL的一般格式为(带方括号[]的为可选项):
protocol :// hostname[:port] / path / [;parameters][?query]#fragment
-
URL的格式由三部分组成:
①第一部分是协议(或称为服务方式)。
②第二部分是存有该资源的主机IP地址(有时也包括端口号)。
③第三部分是主机资源的具体地址,如目录和文件名等。
第一部分和第二部分用“://”符号隔开,
第二部分和第三部分用“/”符号隔开。
第一部分和第二部分是不可缺少的,第三部分有时可以省略。
5、URL和URI简单比较
-
URI属于父类,而URL属于URI的子类。URL是URI的一个子集。
-
URI的定义是:统一资源标识符;URL的定义是:统一资源定位符。
-
URI表示请求服务器的路径,定义这么一个资源。而URL同时说明要如何访问这个资源
6,文件的URL
-
用URL表示文件时,服务器方式用file表示,后面要有主机IP地址、文件的存取路 径(即目录)和文件名等信息。有时可以省略目录和文件名,但“/”符号不能省略。
-
例:file://ftp.yoyodyne.com/pub/files/foobar.txt
上面这个URL代表存放在主机ftp.yoyodyne.com上的pub/files/目录下的一个文件,文件名是foobar.txt。
例:file://ftp.yoyodyne.com/pub
代表主机ftp.yoyodyne.com上的目录/pub。 例:file://ftp.yoyodyne.com/
代表主机ftp.yoyodyne.com的根目录。
附:爬虫最主要的处理对象就是URL,它根据URL地址取得所需要的文件内容,然后对它 进行进一步的处理。
robots.txt协议
有些网站会在robots协议里面标注哪些数据可以爬取,属于君子协议啦
http协议和https协议
https更安全
常用请求头信息
- User-Agent:请求载体的身份标识
- Connection:请求完毕后,是断开连接还是保持连接
常用响应头信息
- Content-Type:服务器响应回客户端的数据类型
加密方式
对称密钥加密 非对称密钥加密 证书密钥加密->找个靠谱的中介
二,利用requests通过指定的URL抓取网页内容
1,怎么用requests模块
1,指定url。2,发起请求 3,获取响应数据 4,持久化存储
- 网页抓取,就是把URL地址中指定的网络资源从网络流中读取出来,保存到本地。
requests:自动爬取HTML页面,自动网络请求提交
2,访问百度网页
- (Response)-> r=requests.get(url) ->(Request)
Response对象属性:
- r.status_code: HTTP请求返回状态。200表示成功,404表示失败
- r.text: url对应的页面内容
- r.encoding:header中猜测的编码方式
- r.apparent_encoding:从内容中分析出来的响应内容的编码方式(r.encoding的备选)
- r.content:HTTP响应内容的二进制形式
#导入数据库
import requests
#指定url发起请求
response=requests.get("http://www.baidu.com")
resoonse.status_code
response.encoding='utf-8'
#获取相应数据
page=response.text
#持久化存储
with open('baidu.html','w',encoding='utf-8') as f:
f.write(page)
//把内容写进创建的baidu.html文件中
//文件夹里多了baidu.html文件
:
3,理解Requests库的异常
Response的异常
-
r.raise_for_status() 内部判断r.status_code是否等于200,若不是200,产生requests.HTTPErrors
-
爬取网页通用代码框架(r.raise_for_status() )
import requests
def getHTMLText(url):
try:
r=requests.get(url,timeout=30)
r.raise_for_status()
r.encoding=r.apparent_encoding
return r.text
except:
return "产生异常"
if __name__=="__main__"://加上此语句后,确保这个代码在自己单独运行时才会执行(getHTMLText)函数。
url="http://www.baidu.com"
print(getHTMLText(url))
三,爬
有的网站能根据你的请求头来判断是正常访问还是爬取。这个时候需要我们去伪装头部
headers={
"user-agent":"Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Mobile Safari/537.36 Edg/96.0.1054.62"
#检查->network
}#找到的身份标识以字典形式记录下来。身份标识是指跟浏览器说通过什么浏览器的什么版本进行访问
response=requests.get("http://cxsjsxmooc.openjudge.cn",headers=header)
- url='https://www.baidu.com/s?wd='+'奥里给',由此推断出
wd=input('请输入你要搜索的内容:')
url= 'https://www.baidu.com/s?wd='+wd
response=requests.get(url=url,headers=header)
- user-agent
- 对百度进行关键字搜索
import requests
header = { # 用字典格式带入浏览器的请求头
"user-agent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Mobile Safari/537.36 Edg/96.0.1054.62"
# 检查->network
}
wd = input('请输入你要搜索的内容:')
url = 'https://www.baidu.com/s?wd='+wd
response = requests.get(url=url, headers=header)
response.status_code
response.encoding = 'utf-8'
page = response.text
with open('fxz.html', 'w', encoding='utf-8') as f:
f.write(page)
requests里.text和.content方法的区别
response = requests.get(url=url, headers=header).text
requests对象的get和post方法都会返回一个Response对象,这个对象里面存的是服务器返回的所有信息,包括响应头,响应状态码等。其中返回的网页部分会存在.content和.text两个对象中。
.text是现成的字符串,.content还要编码,但是.text不是所有时候显示都正常,这是就需要用.content进行手动编码。
大部分情况建议使用text,因为显示的是汉字,但有时会显示乱码,这时用content.decode('utf-8'),中文常用utf-8和GBK,GB2312等。这样可以手工选择文字编码方式。
上面的内容转自python requests的content和text方法的区别_百度知道
爬亚马逊商品
爬美女
-
需要对python中的文件以及文件夹或者其他的进行一系列操作,引入os模块
xpath
-
xpath 可以在抓包工具里复制,如果不管用就手打。
-
// 的意思是不用从根目录开始,在中间是两个标签的直接跳转。
-
开头只打一个斜线就是要从/html开始了.中间/是一层一层递进
-
若是有标签名,格式类似于//div[@class="a"]
-
推下去后选择要取得的信息:若是文本信息,末尾加/text()。若是标签里的属性,则是/a/@href.若是很多相同元素在同一级,可以用这么写:两个div在同一级用div[1],div[2]来表示
上面内容转载自(70条消息) 一起学爬虫(Python) — 05_小泽-CSDN博客
import os
import requests
from lxml import etree
# 需要对python中的文件以及文件夹或者其他的进行一系列操作,引入os模块
header = {
"user-agent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Mobile Safari/537.36 Edg/96.0.1054.62"
}
url = 'http://www.win4000.com/zt/dongman.html'
response = requests.get(url=url, headers=header).text # 读取第一个url
tree = etree.HTML(response) # 树化第一个页面
# 把文本形式的网页数据变成大树,用etree.HTML()大树化
leaf = tree.xpath('//div[@class="tab_box"]//ul[@class="clearfix"]/li/a/@href')
# xpath 可以在抓包工具里复制,如果不管用就手打.
# 最后的@href是直接艾特我们要的数据
# 创立一个新文件夹
if not os.path.exists('./美女'): # 如果该文件夹不存在,则创建
os.mkdir('./美女')
# 遍历每一张图片对应的第二张图片
for a in leaf:
# 防止出错终止循环
try:
b = 1
# 获取循环图集里的每一张图片,默认最多10张
while b < 11:
c = a.split('.html')[0]
# 复习一下split() 以.html为分割符,以[0]为索引,保留第一段
d = c+'_'+str(b)+'.html'
b += 1
# 每个图片都包含着很多图片。重复之前步骤
e = requests.get(url=d, headers=header).text
f = etree.HTML(e)
# 提取列表里第一个元素
g = f.xpath(
'//div[@class="main"]//div[@class="pic-meinv"]/a/img/@src')[0]
# 给图片起名字
# http://pic1.win4000.com/wallpaper/3/5333b467c7f5a.jpg
i = '美女/'+g.split('/')[-1]
h = requests.get(url=g, headers=header).content
# 图片以二进制形式保留在本地。不是text,也没有汉字不用utf-8
# 持久化存储
with open(i, 'wb') as pp:
pp.write(h)
except:
print("出错啦!")
对于这个爬取,我是这样理解的
,1,指定url
2,发起请求
3,获取响应数据
- 使用requests.get()方法获取网页上的HTML内容
- 通过lxml库的etree.HTML来解析这个网页结构
- 最后通过xpath来获取自己所需内容
4,持久化存储
vscode显示lxml找不到
版本需要更新,这篇文章讲的很清晰 ,如果更新完还是不可以,可以重启一下电脑
如何在cmd里面切换目录
cd+空格+文件名(要层层递进)
这个代码跟着敲后爬不出美女,不知道是不是网站的原因,那我们换个网站。随便找个网站看能不能爬
跟着这个思路,试着自己爬取一个网站
- 提问:怎么找到对应的headers:其实打开检查后,network里面任意一个文件打开就行。user-agent是用户代理。不同文件的user-agent都是一样的.
- 新建文件夹:是个好东西,记住记住
if not os.path.exists('./帅哥'):
os.mkdir('./帅哥')
import os
import requests
from lxml import etree
headers = {
"user-agent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Mobile Safari/537.36 Edg/96.0.1054.62"}
url = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'#具体网址就不发了
r = requests.get(url=url, headers=headers).text
tree = etree.HTML(r)
leaf = tree.xpath('//div[@class="PictureList"]/ul/li/a/@href')
if not os.path.exists('./帅哥'):
os.mkdir('./帅哥')
for a in leaf:
try:
b = 1
while b < 11:
b = b+1
c = a.split('.html')[0]
t = c+'_'+str(b)+'.html'
f = requests.get(url=t, headers=headers).text
g = etree.HTML(f)
w = g.xpath('//div[@class="ArticleImageBox"]//a/img/@src')[0]
r = requests.get(url=w, headers=headers).content
i = '帅哥/'+w.split('/')[-1]
with open(i, 'wb') as fp:
fp.write(r)
except:
print('出错啦!')
结果显示
成功了!