为什么要进行模拟登陆
为什么需要识别验证码
验证码识别:借助于线上的一款打码平台(超级鹰,云打码,打码兔)
超级鹰的使用流程:http://www.chaojiying.com/about.html
cookie操作:
模拟登陆案例
#模拟登陆爬取古诗文网站登陆界面
import requests
from lxml import etree
from chaojiying_Python.chaojiying import Chaojiying_Client
#当你处理登陆爬虫时要将请求换成session
session = requests.Session()
#将超级鹰下载的包封装成一个函数进行引入调用
def get_codeImg_text(imgPath, imgType):
chaojiying = Chaojiying_Client('超级鹰账号', '超级鹰密码', ' 899991') #用户中心>>软件ID 生成一个替换 96001
im = open(imgPath, 'rb').read() #本地图片文件路径 来替换 a.jpg 有时WIN系统须要//
# print(chaojiying.PostPic(im, 1902))
return chaojiying.PostPic(im, imgType)['pic_str']
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36"
}
#模拟登录
#获取验证码图片
url = 'https://so.gushiwen.org/user/login.aspx?from=http://so.gushiwen.org/user/collect.aspx'
#解析验证码图片
page_text = requests.get(url=url,headers=headers).text
tree = etree.HTML(page_text)
code_img_src = 'https://so.gushiwen.org/'+tree.xpath('//*[@id="imgCode"]/@src')[0]
code_img_data = session.get(url=code_img_src,headers=headers).content
with open('./code.jpg','wb') as fp:
fp.write(code_img_data)
#解析动态参数
__VIEWSTATE = tree.xpath('//input[@id="__VIEWSTATE"]/@value')[0]
__VIEWSTATEGENERATOR = tree.xpath('//input[@id="__VIEWSTATEGENERATOR"]/@value')[0]
print(__VIEWSTATE,__VIEWSTATEGENERATOR)
#使用打码平台识别出来的验证码图片数据
codeImg_text = get_codeImg_text('./code.jpg',1902)
print(codeImg_text)
login_url = 'https://so.gushiwen.org/user/login.aspx?from=http%3a%2f%2fso.gushiwen.org%2fuser%2fcollect.aspx'
#动态参数:动态参数往往都会被隐藏在前台页面
data = {
#处理了动态参数
"__VIEWSTATE": __VIEWSTATE,
"__VIEWSTATEGENERATOR": __VIEWSTATEGENERATOR,
"from": "http://so.gushiwen.org/user/collect.aspx",
"email": "你的账号",
"pwd": "你的密码",
"code": codeImg_text,
"denglu": "登录",
}
#登陆发送post请求,且传送data
pages_text = session.post(url=login_url,headers=headers,data=data).text
with open('./gushiwen.html','w',encoding='utf-8') as fp:
fp.write(pages_text)
在爬取数据的时候可能会报出一个HttpConnectilonPool的错误
代理:
什么是高匿名、匿名和透明代理?他们有什么区别?
类型:
简单的ip代理演示
url = 'https://www.baidu.com/s?wd=ip'
page_text = requests.get(url=url,headers=headers,proxies={'http':'177.91.254.51:9999'})
with open('./ip.html','w',encoding='utf-8') as fp
fp.wirte(page_text)
线程池:尽可能用在耗时较为严重的操作中
视频的请求下载
视频的持久化存储
使用模块
#模块引入
from multiprocessing.dummy import Pool
#创建线程数量
pool = Pool(4)
pool.map(func,iterable,chunksize=None)
#map方法可以基于异步实现:让参数1对应的函数对参数2对应的容器元素一次进行操作,参数二必须是可迭代的,比如最典型的列表
模拟请求阻塞操作
普通的访问方式
import time
def my_request(url):
print('正在请求:',url)
#设置了休眠等待
time.sleep(10)
print('请求完毕:', url)
urls = [
'www.1.com',
'www.2.com',
'www.3.com',
'www.4.com',
]
start = time.time()
for url in urls:
my_request(url)
print(time.time()-start)
使用线程池
#使用线程池
import time
from multiprocessing.dummy import Pool
pool = Pool(4)
def my_request(url):
print('正在请求:',url)
time.sleep(10)
print('请求完毕:', url)
urls = [
'www.1.com',
'www.2.com',
'www.3.com',
'www.4.com',
]
start = time.time()
pool.map(my_request,urls)
print(time.time()-start)
pool.close()
#join的意思是让主线程等待子线程全部结束后再结束
pool.join()
案例:对梨视频的视频爬取
#对梨视频的视频爬取
import re,random
import requests
from lxml import etree
from multiprocessing.dummy import Pool
pool = Pool(4)
#定义一个函数,传送每一个url,下载视频
def downloadDate(url):
#content爬取二进制使用
return requests.get(url=url,headers=headers).content
#定义一个函数,存储每一个视频
def saveDate(data):
name = str(random.randint(0,10000))+'mp4'
with open(name,'wb') as fp:
fp.write(data)
print(name,'下载成功')
url = 'https://www.pearvideo.com/category_1'
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36"
}
page_text = requests.get(url=url,headers=headers).text
tree = etree.HTML(page_text)
li_list = tree.xpath('//ul[@id="listvideoListUl"]/li')
#定义一个空列表存放所有的视频链接
urls = []
for li in li_list:
detail_url = 'https://www.pearvideo.com/'+li.xpath('./div/a/@href')[0]
pages_text = requests.get(url=detail_url,headers=headers).text
ex = 'srcUrl="(.*?)",vdoUrl'
video_url = re.findall(ex,pages_text,re.S)[0]
urls.append(video_url)
#在耗时较为严重的地方使用线程池,视频的请求下载及持久化存储
#让函数对urls中的每一个元素进行异步网络请求下载
#函数不能传参,不能加括号
#datas是一个列表,存储的是所有的视频二进制的数据
datas = pool.map(downloadDate,urls)
pool.map(saveDate,datas)
pool.close()
#join的意思是让主线程等待子线程全部结束后再结束
pool.join()
#在获取视频链接的时候发现视频并不是存储在标签中,而是在js中的变量里,
# 此时我们只能使用支持各种匹配的正则来获取链接
"""
var contId="1565375",liveStatusUrl="liveStatus.jsp",
liveSta="",playSta="1",autoPlay=!1,isLiving=!1,isVrVideo=!1,
hdflvUrl="",sdflvUrl="",hdUrl="",sdUrl="",ldUrl="",
srcUrl="https://video.pearvideo.com/mp4/short/20190612/cont-1565375-14010027-hd.mp4",
vdoUrl=srcUrl,skinRes="//www.pearvideo.com/domain/skin",videoCDN="//video.pearvideo.com";
"""
爬取喜马拉雅中的相声
#爬取喜马拉雅中的相声
import requests
from multiprocessing.dummy import Pool
pool = Pool(10)
#定义一个函数,传送每一个url,下载视频
def downloadDate(url):
# content爬取二进制使用
return requests.get(url=url,headers=headers).content
#定义一个函数,存储每一个视频
def saveDate(data):
i = 0
print(data)
with open(name_list[i],'wb') as fp:
fp.write(data)
print(name_list[i], '下载成功')
i += 1
url = 'https://www.ximalaya.com/revision/play/album?albumId=9723091&pageNum=%d&sort=0&pageSize=30'
for page in range(1,2):
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36"
}
params = {
"albumId": "9723091",
"pageNum": page,
"sort": "0",
"pageSize": "30"
}
new_url = format(url%page)
#该数据为json数据,需要使用json进行解读,要带括号
page_json = requests.get(url=new_url,headers=headers,params=params).json()
pages_json = page_json['data']['tracksAudioPlay']
src_list = [] #存放下音频连接
name_list = [] #存放音频名字
for pages in pages_json:
src_list.append(pages['src'])
name_list.append(pages['trackName'])
# datas是一个列表,存储的是所有的音频二进制的数据
datas = pool.map(downloadDate,src_list)
print(datas)
pool.map(saveDate,datas)
pool.close()
pool.join()
原文:https://www.cnblogs.com/Godisgirl/p/11020292.html