文章目录
1-爬取搜狗首页的页面数据
import requests
if __name__ == "__main__":
#step1:指定url
url='https://www.sogou.com/'
#steo2:发起请求get:get方法返回值是一个响应对象
response = requests.get(url=url)
#step3:获取响应数据
page_text = response.text #text返回的是字符串形式的响应数据
print(page_text)
#step4:持久化存储
with open('./sogou.html','w',encoding='utf-8') as fp:
fp.write(page_text)
print("爬取数据结束!")
2-爬取搜狗指定词条对应的搜索结果页面——UA检测 | UA伪装
2-1带参数params
import requests
if __name__ == "__main__":
#step1:
url = 'https://www.sogou.com/sogou'
#处理url携带的参数:封装到字典中
kw = input('enter a word:')
param = {
'query':kw
}
#step2:
#对指定的url发起请求对应的url是携带参数的,并且请求过程中处理了参数
response = requests.get(url=url,params=param)
#step3:
page_text = response.text
fileName = kw+'.html'
with open(fileName,'w',encoding='utf-8') as fp:
fp.write(page_text)
print(fileName+"保存成功")
原始网站
https://www.sogou.com/sogou?query=%E6%9E%97%E4%BD%B3%E9%9B%AF&_asf=www.sogou.com&_ast=1612188228&w=01019900&p=40040100&ie=utf8&from=index-nologin&s_from=index&pid=sogou-site-1f2b8183cd1e469a
参数很多!query是核心参数,其后面是要搜索的字符串
修改:
https://www.sogou.com/sogou?query=%E6%9E%97%E4%BD%B3%E9%9B%AF
中文变成乱码了
2-2UA伪装——用header
UA:User-Agent(请求载体的身份标识)
UA检测:门户网站的服务器会检测对应请求的载体身份标识。如果检测到请求的载体身份标识为某一浏览器,那么说明该请求是正常的请求。如果检测到请求的载体身份标识不是基于某一款浏览器的,则标识不是基于某一款浏览器的,则表示该请求为不正常的请求(爬虫),则服务器端就很可能拒绝该次请求。UA伪装:让爬虫对应的请求载体身份标识伪装成某一款浏览器;将对应的User-Agent封装到一个字典中。
import requests
if __name__ == "__main__":
#UA伪装:将对应的User-Agent封装到一个字典中
header = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36 Edg/88.0.705.56'
}
#step1:
url = 'https://www.sogou.com/sogou'
#处理url携带的参数:封装到字典中
kw = input('enter a word:')
param = {
'query':kw
}
#step2:
#对指定的url发起请求对应的url是携带参数的,并且请求过程中处理了参数
response = requests.get(url=url,params=param,headers=header)
#step3:
page_text = response.text
fileName = kw+'.html'
with open(fileName,'w',encoding='utf-8') as fp:
fp.write(page_text)
print(fileName+"保存成功")
3-破解百度翻译
我们想要的是翻译的结果,某个单词或句子的文本数据,而非一整个页面。是页面的局部数据。
【页面局部刷新】——用ajax
【需求】
--post请求(携带了参数)
--响应数据是json数据
import requests
import json
if __name__ == "__main__":
#step1:指定url
post_url = 'https://fanyi.baidu.com/sug'
#step2:进行UA伪装:伪装成是浏览器在发起请求
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36 Edg/88.0.705.56'
}
#step3:post请求参数处理(同get请求一致)
data = {
'kw': 'cat'
}
#step4:请求发送
response = requests.post(url=post_url,data=data,headers=headers)
#step5:获取响应数据:json()返回的是一个字典对象(如果确认响应数据是json类型的,才用这个方法)
dic_obj = response.json()
#step6:进行持久化存储
fp = open('./cat.json','w',encoding='utf-8')
json.dump(dic_obj,fp=fp,ensure_ascii=False)
print("保存成功!")
变成动态的
import requests
import json
if __name__ == "__main__":
#step1:指定url
post_url = 'https://fanyi.baidu.com/sug'
#step2:进行UA伪装:伪装成是浏览器在发起请求
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36 Edg/88.0.705.56'
}
#step3:post请求参数处理(同get请求一致)
word = input("请输入单词:")
data = {
'kw':word
}
#step4:请求发送
response = requests.post(url=post_url,data=data,headers=headers)
#step5:获取响应数据:json()返回的是一个字典对象(如果确认响应数据是json类型的,才用这个方法)
dic_obj = response.json()
print(dic_obj)
#step6:进行持久化存储
fileName = word+'.json'
fp = open(fileName,'w',encoding='utf-8')
json.dump(dic_obj,fp=fp,ensure_ascii=False)
print("保存成功!")
4-爬取豆瓣电影分类排行榜
需求:爬取豆瓣电影分类排行榜 https://movie.douban/com/中的电影详细数据
页面滚动到底部时,又会更新出新的数据【地址栏没变】——【页面局部更新】
import requests
import json
if __name__ == "__main__":
#step1:指定url
url = 'https://movie.douban.com/j/chart/top_list'
#url参数处理_字典封装
param = {
'type': '24',
'interval_id': '100:90',
'action': '',
'start': '0', #从豆瓣的库中的第几部电影开始取
'limit': '20', #一次取多少个
}
#step2:进行UA伪装:伪装成是浏览器在发起请求
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36 Edg/88.0.705.56'
}
response = requests.get(url=url,params=param,headers=headers)
list_data = response.json()
fp = open('./douban.json','w',encoding='utf-8')
json.dump(list_data,fp=fp,ensure_ascii=False)
print("保存成功!")
5-爬取肯德基餐厅数据
需求:爬取肯德基http://www.kfc.com.cn/kfccda/index.aspx中的指定地点的餐厅数
6-爬取国家药品监督管理总局中基于中华人民共和国化妆品生产许可证相关数据
6-1-需求
- 爬取药监总局中相关企业的详情信息http://scxk.nmpa.gov.cn:81/xk/
6-2-需求分析
-
确定页面中企业相关数据是否为动态加载?
- 相关的企业信息是动态加载出来的
-
通过抓包工具实现全局搜索,定位动态加载数据对应的数据包!
- post:http://scxk.nmpa.gov.cn:81/xk/itownet/portalAction.do?method=getXkzsList
- 该请求返回的响应数据是一组json串,通过对json串的一个简单分析,没有找到企业详情页的url,但是找到个每一家企业的id
-
每一家企业详情页的url,域名都是一样的,只有请求参数id值不同
-
可以使用同一个域名结合着不同企业的id值拼接成一家完整企业详情页url
-
判断企业详情页中的数据是否为动态加载?
-
通过抓包工具检测,发现企业详情信息在详情页中为动态加载的数据
-
通过抓包工具实现全局搜索定位动态加载数据对应的数据包
-
post-url:
http://scxk.nmpa.gov.cn:81/xk/itownet/portalAction.do?method=getXkzsById
- 请求参数:id=xxxxx
-
请求到的json串就是我们最终想要的企业详情信息数据
-
-
-
import requests
import json
if __name__ == "__main__":
#step1:指定url
url = 'http://scxk.nmpa.gov.cn:81/xk/'
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36 Edg/88.0.705.56'
}
response = requests.get(url=url,headers=headers)
page_text = response.text
with open('./huazhuangpin.html','w',encoding='utf-8') as fp:
fp.write(page_text)
跟原始页面对比:
修改:相关的企业信息是动态加载出来的
动态加载数据:
首页中的企业信息是根据Ajax动态请求得到的
http://scxk.nmpa.gov.cn:81/xk/itownet/portal/dzpz.jsp?id=f9b93ef62c984148b289ab30c02ebb66
http://scxk.nmpa.gov.cn:81/xk/itownet/portal/dzpz.jsp?id=03f52d584b954abdae1e39e98a11071c
通过对详细页url的观察发现:
不同的企业对应的id值不一样
通过详细页面url的观察发现,url的域名都是一样的,只有携带的参数(id)不一样。
id值可以从首页对应的Ajax请求中的json串中获取
详细页的企业详细数据也是动态加载出来的。
观察后发现:所有的post请求的url都是一样的,只有参数的id值是不一样的。
如果我们可以批量获得不同企业的id后,就可以将id和url形成一个完整的详情页对应详情数据的ajax请求的url
如何批量获取id数据?
首页就有很多
import requests
#step1:获取每一家企业的id
url = 'http://scxk.nmpa.gov.cn:81/xk/itownet/portalAction.do?method=getXkzsList'
#参数的封装
data = {
'on': 'true',
'page': '1',
'pageSize': '15',
'productName':'' ,
'conditionType': '1',
'applyname':'',
'applysn': '',
}
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36 Edg/88.0.705.56'
}
json_ids = requests.post(url=url,headers=headers,data=data).json()
id_list = [] #存储企业的id
all_data_json = []# 存储企业的详情数据
for dic in json_ids['list']:
id_list.append(dic['ID'])
#step2:获取某一企业详情信息
post_url = 'http://scxk.nmpa.gov.cn:81/xk/itownet/portalAction.do?method=getXkzsList'
for id in id_list:
data = {
'id' : id
}
detail_json = requests.post(url=post_url,headers=headers,data=data).json()
all_data_json.append(detail_json)
#持久化存储
fp = open('./allData.json','w',encoding='utf-8')
json.dump(all_data_json,fp=fp,ensure_ascii=False)
⭐处理分页的操作
import requests
#step1:获取每一家企业的id
url = 'http://scxk.nmpa.gov.cn:81/xk/itownet/portalAction.do?method=getXkzsList'
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36 Edg/88.0.705.56'
}
id_list = [] #存储企业的id
all_data_json = []# 存储企业的详情数据
#参数的封装
for page in range(1,6):
page = str(page)
data = {
'on': 'true',
'page': page,
'pageSize': '15',
'productName':'' ,
'conditionType': '1',
'applyname':'',
'applysn': '',
}
json_ids = requests.post(url=url,headers=headers,data=data).json()
for dic in json_ids['list']:
id_list.append(dic['ID'])
#step2:获取某一企业详情信息
post_url = 'http://scxk.nmpa.gov.cn:81/xk/itownet/portalAction.do?method=getXkzsList'
for id in id_list:
data = {
'id' : id
}
detail_json = requests.post(url=post_url,headers=headers,data=data).json()
all_data_json.append(detail_json)
#持久化存储
fp = open('./allData.json','w',encoding='utf-8')
json.dump(all_data_json,fp=fp,ensure_ascii=False)
7-爬取糗事百科中糗图板块下所有的糗图图片
有图片有文字——但我们只要图片——如何爬取图片?
import requests
if __name__ == "__main__":
url = 'https://pic.qiushibaike.com/system/pictures/12400/124000872/medium/2ZGYUXAUGWHAY5CM.jpg'
#content返回的是二进制形式的图片数据
#text(字符串) content(二进制) json()(对象)
img_data = requests.get(url=url).content
with open('./qiutu.jpg','wb') as fp:
fp.write(img_data)
先爬取一整张网页,再解析局部数据获取图片。
import requests
import re
import os
if __name__ == "__main__":
#创建一个文件夹保存所有的图片
if not os.path.exists('./qiutuLibs'):
os.mkdir("./qiutuLibs")
url='https://www.qiushibaike.com/imgrank/'
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36 Edg/88.0.705.56'
}
#使用通用爬虫对url对应的一整张页面进行爬取
page_text = requests.get(url=url,headers=headers).text
#使用聚焦爬虫将页面中的所有糗图进行解析和提取
ex = '<div class="thumb">.*?<img src="(.*?)" alt.*?</div'
img_src_list = re.findall(ex,page_text,re.S)
for src in img_src_list:
#拼接出一个完整的图片地址
src = "https:"+src
#请求到了图片的二进制地址
img_data = requests.get(url=src,headers=headers).content
img_name = src.split('/')[-1]
imgPath = './qiutuLibs/'+img_name
with open(imgPath,'wb') as fp:
fp.write(img_data)
print(img_name+'下载成功')
要将页面的所有src全部获取——图片都在<class='thumb>里面
<div class="thumb">
<a href="/article/124000872" target="_blank">
<img src="//pic.qiushibaike.com/system/pictures/12400/124000872/medium/2ZGYUXAUGWHAY5CM.jpg" alt="糗事#124000872" class="illustration" width="100%" height="auto">
</a>
</div>
对应的正则表达式
ex = '<div class="thumb">.*?<img src="(.*?)" alt.*?</div'
分页处理
第一页对应的url
https://www.qiushibaike.com/imgrank/
第一页改成 :https://www.qiushibaike.com/imgrank/page/1/ 也是可以的
第三页对应的url
https://www.qiushibaike.com/imgrank/page/3/
import requests
import re
import os
if __name__ == "__main__":
#创建一个文件夹保存所有的图片
if not os.path.exists('./qiutuLibs'):
os.mkdir("./qiutuLibs")
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36 Edg/88.0.705.56'
}
#设置一个通用的url模板
url='https://www.qiushibaike.com/imgrank/'
for pageNum in range(1,3):
#对应页码的url
new_url = url+str(pageNum)
#使用通用爬虫对url对应的一整张页面进行爬取
page_text = requests.get(url=new_url,headers=headers).text
#使用聚焦爬虫将页面中的所有糗图进行解析和提取
ex = '<div class="thumb">.*?<img src="(.*?)" alt.*?</div'
img_src_list = re.findall(ex,page_text,re.S)
for src in img_src_list:
#拼接出一个完整的图片地址
src = "https:"+src
#请求到了图片的二进制地址
img_data = requests.get(url=src,headers=headers).content
img_name = src.split('/')[-1]
imgPath = './qiutuLibs/'+img_name
with open(imgPath,'wb') as fp:
fp.write(img_data)
print(img_name+'下载成功')
参考资料
根据B站《Python超强爬虫8天速成》系列视频整理而成