for i in range(2, 4):
# 一定要在循环内,否则一直为"https://pic.netbian.com/4kmeinv/index_2.html"
# 关于为什么后面是/4kmeinv/index_{0}.html 代码后讲解
url = "https://pic.netbian.com/4kmeinv/index_{0}.html"
url = url.format(i)
#方法一
#先获取网页的HTML
#page=requests.get(url=url,headers=headers).text #乱码了
respone=requests.get(url=url,headers=headers)
#手动设定解决乱码
respone.encoding="utf-8" #乱码没解决
page=respone.text
#方法二
# 通用处理中文乱码的解决方案
img_name=img_name.encode('iso-8859-1').decode('gbk')
#print(img_name)
1. 文字乱码
.encode("iso-8859-1").decode('gbk')
.encode("iso-8859-1").decode('utf-8')
.encode("iso-8859-1")
.encode("utf-8")
都可尝试一下
3. 还有就是文件格式打开,rar问价是二进制文件,"wb"方式打开
5. 关于xpath表达式返回空列表:
除了正则表达式错误外,我们也可以检查一下在运行过程中对数据读取的情况是否和我们页面上内容一致
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
语法:
网址:https://www.json.cn/
requests主要有两个小的数据请求方式get和post
如何在网页上进行分辨呢?
https://movie.douban.com/typerank?type_name=%E5%96%9C%E5%89%A7&type=24&interval_id=100:90
用该网址举三个例子:
#uA伪装
headers={
'User-Agent':''
}
#例子1
url='https://movie.douban.com/typerank?type_name=%E5%96%9C%E5%89%A7&type=24&interval_id=100:90'
param={}
response=requests.get(url=url,params=param,headers=headers)
#例子2
url='https://movie.douban.com/typerank?'
param={
"type_name":"%E5%96%9C%E5%89%A7",
"type":'24',
"interval_id":'100:90'
}
response=requests.get(url=url,params=param,headers=headers)
#例子3
param={
"type_name":"%E5%96%9C%E5%89%A7",
"type":'24',
}
response=requests.get(url='https://movie.douban.com/typerank?interval_id=100:90',params=param,headers=headers)
例如爬取:爬取搜狗指定词条对应的搜索结果页面
import requests
if __name__=="__main__":
url='https://www.sogou.com/web?' #https://www.sogou.com/web?query=你好李焕英
#处理url携带的参数:封装到字典中
world=input('请输入搜索内容')
param={
'query':world #query=你好李焕英
}
#UA伪装
headers={
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36'
}
#对指定的url发起的请求对应的url是携带参数的,并且请求过程中处理了参数
#url请求过程中动态拼接了param
response=requests.get(url=url,params=param,headers=headers)
page=response.text
#输出文件的命名
kw=world+'.html'
with open(kw,'w',encoding='utf-8') as fp:
fp.write(page)
print("爬虫完毕")
首先我们要了解百度翻译的机制(阿贾克斯请求):
1. url的确定
2. User-Agent的确定
3. data数据内容
4. response数据返回类型
5. Request Method 请求方式
阿贾克斯(Ajax):当我们在打开一个界面时输入相应的内容,并没有按下回车键,就会自动帮我们搜索相应的结果,这个过程就称为阿贾克斯请求。在电脑端的百度,谷歌等浏览器中经常见到。(我们打开一个界面检查后,进入Network,在网址不改变的情况下看到的新Name就是阿贾克斯请求)
在进行阿贾克斯请求时网址是不变的啊!!!
在进行阿贾克斯请求时网址是不变的啊!!!
在进行阿贾克斯请求时网址是不变的啊!!!
需求:破解百度翻译
import requests
import json
if __name__=="__main__":
#1.指定url
post_url='https://fanyi.baidu.com/sug'
#2.UA伪装
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36'
}
#post请求参数处理(同get请求一致)
word=input('请输入一个单词:')
data={
'kw':word
}
#4.请求发送
response=requests.post(url=post_url,data=data,headers=headers)
#5.获取响应数据:json()方法返回的是obj
#如果确认响应数据是json类型的,才可以使用json()
page=response.json()
#持久化存储
fp=word+'.json'
filename=open(fp,'w',encoding='utf-8')
json.dump(page,fp=filename,ensure_ascii=False)
fp.close()#打开后一定要关闭文件,否则不能在文件中看到存储内容
#4.请求发送
response=requests.post(url=post_url,data=data,headers=headers)
#5.获取响应数据:json()方法返回的是obj
#如果确认响应数据是json类型的,才可以使用json()
page=response.json()
#持久化存储
fp=word+'.json'
filename=open(fp,'w',encoding='utf-8')
json.dump(page #储存数据
,fp=filename #存储地址
,ensure_ascii=False)#是否以ASCLL内容格式存储,由于翻译内容包含汉字,而ASCLL中没有汉字,所以False.
豆瓣电影:
import json
import requests
url="https://movie.douban.com/j/chart/top_list?"
header={
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36 SLBrowser/7.0.0.5211 SLBChan/25"
}
param={
'type': '24'
,'interval_id': '100:90'
,'action':''
,'start': '0'#爬去开始位置
,'limit': '10'#每次爬取数据个数
}
response=requests.get(url=url
,params=param
,headers=header)
page_json=response.json()
print(page_json)
fp = open(file="dou_ban.json",mode='w+',encoding="utf-8")
json.dump(page_json,fp=fp,ensure_ascii=False)
fp.close()
print("爬爬爬over")
这是保存的数据(我们没法用):
那么----------展开第一个object,哇哇哇!!!
import json
import requests
url="https://movie.douban.com/j/chart/top_list?"
header={
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36 SLBrowser/7.0.0.5211 SLBChan/25"
}
param={
'type': '24'
,'interval_id': '100:90'
,'action':''
,'start': '0'#爬去开始位置
,'limit': '10'#每次爬取数据个数
}
response=requests.get(url=url
,params=param
,headers=header)
movie_json=response.json()
fp = open(file="movie_rank.html",mode='w+',encoding="utf-8")
for each_movie in movie_json:
json.dump([each_movie['rank'],each_movie['title']], fp=fp, ensure_ascii=False)
fp.write('\n')
fp.close()
print("爬爬爬over")
这是获取后的:
#整体
json.dump(page_json,fp=fp,ensure_ascii=False)
fp.close()
print("爬爬爬over")
#局部
for each_movie in movie_json:
json.dump([each_movie['rank'],each_movie['title']], fp=fp, ensure_ascii=False)
fp.write('\n')
fp.close()
print("爬爬爬over")
国药和百度图片:https://www.cdsy.xyz/computer/programme/Python/20221019/cd166617660737323.html
聚焦爬虫:简单的来说就是爬取目标界面中特定的数据。对于一整页网页数据,我们有时候想要的内容仅仅是某些特定的信息,就像我们拿到某页的网址,仅仅是想要里面的小姐姐的图片,而不想要其他的。那么我们如何针对性的爬取我们所想要的信息呢???那么我们就需要用到数据解析帮助我们
数据解析类别
数据解析原理:
聚爬编码流程:
1.实例化一个etree的对象,且需要将被解析的页面源码数据加载到该对象中。
2.调用etree对象中的xpath方法结合着xpath表达式实现标签的定位和内容的捕获。
pip install lxml
etree.parse(filrPath)
etree.HTML('page_text')
xpath('Xpath表达式')
例如:test.html中的根节点是html
#定位到title标签
r=tree.xpath('/html/head/title') #从根节点开始一层一层去定位,返回的列表,返回的是element对象,不是具体内容
print(r) #输出是列表
'''
输出:[<Element title at 0x26ed87de2c0>]
'''
#有几个div,返回列表中就有几个Element
r = tree.xpath('/html/body/div') # 从根节点开始一层一层去定位,返回的列表,返回的是element对象,不是具体内容
print(r)
'''
输出:[<Element div at 0x2041d1ee400>, <Element div at 0x2041d1ee480>, <Element div at 0x2041d1ee4c0>]
'''
#有几个div,返回列表中就有几个Element
r = tree.xpath('//div') # 同
print(r)
div[@class='song'] tag[@attrName="attrValue"]
#例子
#属性定位
r = tree.xpath('//div[@class="song"]') #[]中括号@是固定格式,返回的是列表
#返回的是[<Element div at 0x2af276df340>]
# 索引定位
r = tree.xpath('//div[@class="song"]/p[3]') # []中索引是从1开始的
print(r) #[<Element p at 0x29af6930180>]
# 定位
r = tree.xpath('//div[@class="tang"]/ul/li[5]/a/text()') # []中索引是从1开始的
print(r) #['杜牧']
r = tree.xpath('//div[@class="tang"]/ul/li[5]/a/text()')[0] #杜牧
# 取文本 //text()
r = tree.xpath('//div[@class="tang"]/ul/li[5]//text()') # []中索引是从1开始的
print(r) #['杜牧']
# 取属性 /@attrName
r = tree.xpath('//div[@class="song"]/img/@src') # @src :@属性 /@attrName
print(r) #['http://www.baidu.com/meinv.jpg']
r = tree.xpath('//div[@class="song"]/img/@src')[0] #http://www.baidu.com/meinv.jpg
#两种导库方式
from lxml import etree
from lxml.html import etree
1. 讲本地html文档加载进该对象中
res=etree.parse('./test.html', etree.HTMLParser())#不需要用ope打开
#对于etree.HTMLParser(),暂时不明白原因,期待大家帮助
#返回<lxml.etree._ElementTree at 0x1fb534d6440>
2. 将互联网上的页面源码加载到对象中(较为常用)
response=requests.get(url,headers=header).text
res=etree.HTML(response)#response必须为text
#返回<Element html at 0x1fb531afa80>
import requests
from lxml import etree
header = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36 SLBrowser/7.0.0.5211 SLBChan/25"
}
url = "https://zz.58.com/ershoufang/"
house_text=requests.get(url=url,headers=header).text
#注意一定有.text 否则报错
house_tree=etree.HTML(house_text)#实例化
res=house_tree.xpath("//section[@class='list']/div[@class='property']/a//h3/text()")
print(res) #输出的是列表
fp=open("test.txt",mode="w+",encoding="utf-8")
for i in res:
fp.write(i+'\n')
fp.write('\n')
fp.close()
#我自己的代码
import requests
from lxml import etree
if __name__=="__main__":
headers={
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36'
}
url='https://zz.58.com/ershoufang/'
page_text=requests.get(url=url,headers=headers).text
#print(page_text)
#数据解析
tree=etree.HTML(page_text)
#r1与r相同 #r1=tree.xpath('//section[@class="list"]/div/a/div[@class="property-content"]/div[@class="property-content-detail"]/div[@class="property-content-title"]/h3/text()')
r = tree.xpath('//div[@class="property-content-title"]/h3/text()')
print(r)
#需求:解析下载图片数据 http://pic.netbian.com/4kmeinv/
import requests
from lxml import etree
import os
if __name__=="__main__":
#创建一个新文件夹
if not os.path.exists('tupian'):
os.mkdir('tupian')
headers={
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36'
}
url='https://pic.netbian.com/4kmeinv/'
#先获取网页的HTML
#page=requests.get(url=url,headers=headers).text #乱码了
respone=requests.get(url=url,headers=headers)
#手动设定解决乱码
#respone.encoding="utf-8" #乱码没解决
page=respone.text
#数据解析
tree=etree.HTML(page)
li_list=tree.xpath('//div[@class="slist"]/ul/li')
#print(li_list)
for li in li_list:
#图片的网址
img_src='https://pic.netbian.com'+li.xpath('./a/img/@src')[0]
#print(img_src)
#图片名字
img_name=li.xpath('./a/img/@alt')[0]+'.jpg'
# 通用处理中文乱码的解决方案
img_name=img_name.encode('iso-8859-1').decode('gbk')
#print(img_name)
#进行持久化存储
img_data=requests.get(url=img_src,headers=headers).content #二进制数据
#图片路径
img_path='tupian/'+img_name
with open(img_path,'wb') as fp:
fp.write(img_data)
print(img_name,'下载成功!!!')
# with open(img_path,'wb') as fp:
# fp.write(img_data)
# print(img_name,"下载成功!!")
import os
import requests
from lxml import etree
header = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36 SLBrowser/7.0.0.5211 SLBChan/25"
}
picture_loc = [] # 图片存地址
picture_name_list = [] # 存图片名
# 第2,3页图片,可自行调节
# 不能包括1,因为1页面网址和后面网址不一样,如想包括,可添加if条件判断
for i in range(2, 4):
# 一定要在循环内,否则一直为"https://pic.netbian.com/4kmeinv/index_2.html"
# 关于为什么后面是/4kmeinv/index_{0}.html 代码后讲解
url = "https://pic.netbian.com/4kmeinv/index_{0}.html"
url = url.format(i)
girl_data = requests.get(url=url, headers=header).text
girl_data = girl_data.encode("iso-8859-1").decode('gbk')
girl_etree = etree.HTML(girl_data, )
# 地址压入
picture_loc.extend(girl_etree.xpath("//ul[@class='clearfix']/li/a/img/@src"))
# 图片名压入
picture_name_list.extend(girl_etree.xpath("//ul[@class='clearfix']/li/a/b/text()"))
if not os.path.exists("you_knew_about_picture"):
os.mkdir("./you_knew_about_picture")
a = 0 # 记录图片个数
for i, each_loc in enumerate(picture_loc):
new_loc = "https://pic.netbian.com/" + each_loc
each_picture_data = requests.get(new_loc, headers=header).content
each_picture_name = "you_knew_about_picture/" + str(a) + " . " + picture_name_list[i] + ".jpg"
fp = open(each_picture_name, mode="wb")
fp.write(each_picture_data)
fp.close()
print(each_picture_name.split("/")[-1] + " have been over")
a = a + 1
print(a)