当前位置: 首页 > 后端技术 > Python

Python多线程爬虫抓取网页图片示例代码

时间:2023-03-25 20:29:20 Python

本文主要介绍Python多线程爬虫抓取网页图片示例代码。一个参考。跟着小编一起来看看吧。目标嗯,我们知道,当你搜索或者浏览网站的时候,会有很多精致漂亮的图片。我们下载的时候,要用鼠标一个一个的下载,甚至翻页。那么,有没有一种非手动方式自动识别和下载图片的方法。美丽的。那么请使用python语言搭建一个爬取和下载网页图片的爬虫。当然,为了提高效率,我们也使用了多线程并行。思路分析Python有很多第三方库可以帮助我们实现各种功能。问题来了,弄清楚我们需要什么:1)http请求库,可以根据网址获取网页的源代码。您甚至可以下载图片并将它们写入磁盘。2)分析网页源代码,识别图片链接地址。比如正则表达式,或者简单的第三方库。3)支持构建多线程或线程池。4)如果可能,需要伪装成浏览器,或者绕过网站验证。(嗯,网站可能会反爬虫?)5)如果可能,还需要自动创建目录、随机数、日期时间等相关内容。所以,我们开始做事。O(∩_∩)O~环境配置操作系统:windows或者linux都可以Python版本:Python3.6(不是Python2.x哦)第三方库urllib.requestthreading或者concurrent.futures多线程或者线程池(python3.6)2+)re正则表达式内置模块os操作系统内置模块编码过程下面我们分解一下这个过程。博客文章末尾提供了完整的源代码。伪装成浏览器importurllib.request#------伪装成浏览器---defmakeOpener(head={'Connection':'Keep-Alive','Accept':'text/html,application/xhtml+xml,*/*','Accept-Language':'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2','Connection':'keep-alive','User-Agent':'Mozilla/5.0(WindowsNT6.1;WOW64;rv:57.0)Gecko/20100101Firefox/57.0'}):cj=http.cookiejar.CookieJar()opener=urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj))header=[]forkey,valueinhead.items():elem=(key,value)header.append(elem)opener.addheaders=headerreturnopener获取外汇赠金活动网页源码http://www.kaifx.cn/activity/#------获取网页源码---#url网页链接地址defgetHtml(url):print('url='+url)oper=makeOpener()ifoperisnotNone:page=oper.open(url)print('-----oper----')else:req=urllib.request.Request(url)#爬虫冒充浏览器req.add_header('User-Agent','Mozilla/5.0(W视窗NT6.1;WOW64;rv:57.0)壁虎/20100101Firefox/57.0')page=urllib.request.urlopen(req)html=page.read()ifcollectHtmlEnabled:#是否采集htmlwithopen('html.txt','wb')asf:f.write(html)#采集本地文件进行分析#------修改html对象中的字符编码ForUTF-8------ifchardetSupport:cdt=chardet.detect(html)charset=cdt['encoding']#使用chardet进行内容分析else:charset='utf8'try:result=html.decode(charset)except:result=html.decode('gbk')returnresult下载单张图片#------根据图片url下载图片------#folderPath定义图片所在目录存储。imgUrl图片索引的链接地址Index,表示图片的数量defdownloadImg(folderPath,imgUrl,index):#------异常处理------try:imgContent=(urllib.request.urlopen(imgUrl)).read()excepturllib.error.URLErrorase:ifprintLogEnabled:print('[Error]当前图片无法下载')returnFalseexcepturllib.error.HTTPErrorase:ifprintLogEnabled:print('[错误]当前图片下载异常')returnFalseelse:imgeNameFromUrl=os.path.basename(imgUrl)ifprintLogEnabled:print('正在下载'+str(index+1)+'图片,图片地址:'+str(imgUrl))#------IO处理------isExists=os.path.exists(folderPath)ifnotisExists:#如果目录不存在,创建os.makedirs(folderPath)print('createdirectory')#图片名称命名规则,随机字符串imgName=imgeNameFromUrliflen(imgeNameFromUrl)<8:imgName=random_str(4)+random_str(1,'123456789')+random_str(2,'0123456789')+"_"+imgeNameFromUrlfilename=folderPath+"\\"+str(imgName)+".jpg"try:withopen(filename,'wb')asf:f.write(imgContent)#写入本地磁盘#ifprintLogEnabled:print('首先下载完成'+str(index+1)+'picture')except:returnFalsereturnTrue批量下载图片(多线程/线程池模式均支持)#------批量下载图片------#folderPath定义了图片存放目录imgListMore图片链接地址defdownloadImgList(folderPath,imgList):index=0#print('poolSupport='+str(poolSupport))ifnotpoolSupport:print('多线程模式')#------多线程编程------threads=[]forimgUrlinimgList:#ifprintLogEnabled:print('准备下载第一个'+str(index+1)+'图片')threads.append(threading.Thread(target=downloadImg,args=(folderPath,imgUrl,index,)))index+=1fortinthreads:t.setDaemon(True)t.start()t.join()#父线程,等待所有线程结束iflen(imgList)>0:print('下载结束,storeimagedirectory:'+str(folderPath))else:print('线程池模式')#------线程池编程------futures=[]#创建最大容量N个任务的线程池的PoolSize是一个全局变量concurrent.futures.ThreadPoolExecutor(max_workers=thePoolSize)aspool:forimgUrlinimgList:#ifprintLogEnabled:print('准备下载第一个'+str(index+1)+'sheetImage')futures.append(pool.submit(downloadImg,folderPath,imgUrl,index))index+=1result=concurrent.futures.wait(futures,timeout=None,return_when='ALL_COMPLETED')suc=0forf结果。done:iff.result():suc+=1print('下载结束,总数:'+str(len(imgList))+',成功次数:'+str(suc)+',存储图片目录:'+str(folderPath))调用示例,以百度贴吧为例#------下载百度帖子中的所有图片------#folderPath定义图片所在的目录url存储百度贴吧链接defdownloadImgFromBaidutieba(folderPath='tieba',url='https://tieba.baidu.com/p/525...'):html=getHtml(url)#------使用正则表达式匹配网页内容查找图片URL------reg=r'src="(.*?\.jpg)"'reg=r'src="(.*?/sign=.*?\.jpg)"'imgre=re.compile(reg)If__name__=='__main__':now=datetime.datetime.now().strftime('%Y-%m-%d%H-%M-%S')#下载百度帖子中的所有图片downloadImgFrom百度贴吧('贴吧\\'+now,'https://贴吧.baidu.com/p/525...')