ons xxx 自动下载 fail 响应 cdn pat pda
因为工作需要,经常需要到新浪某博客去找资料,在博文目录里一页页地肉眼搜索,看到合适的标题再点击开链接查看内容,知道合适地再复制下来。很烦人。于是一直有个想法,学会爬虫。
拿着单位发的购书卡去买了本入门的书《python 编程从入门到实践》,凭着一点编程的底子,三个小时看完了基础部分,然后安装 python 就开始搜集各种网络文字教程,开始实践。
(一)正则标题式提取博文文字
新浪博客博文一句话可以放在几个标签里面,感觉很奇葩 (也许就是我无知)。因为乱七八糟的缘故,sir 学习了一下 re 正则表达式模块,然后开始动手
- #导入request方法
- from urllib import request
- #导入正则表达式模块
- import re
- #打开网页,获取响应文本
- response=request.urlopen('http://blog.sina.com.cn/s/blog_xxxxxxx.html')
- #读取网页源码 不知道怎么表达这个东西
- page=response.read()
- #转码
- js= page.decode('utf-8')
- #编译匹配模式
- pat=re.compile(r'((?<=>)[^>]+?(?=</FONT>)|(?<=>)[^>]+?(?=</SPAN>))')
- #匹配网页内容
- match=re.findall(pat,js)
- #若匹配则输出
- if match:
- n=0
- for each_match in match:
- n+=1
- print(n," : "+each_match +'\n')
正则匹配模式写得不够完美把极少数的无关的内容匹配出来,加上各种网络教程各种的看不懂,使得 sir 失去了努力的方向。
(二)根据 Excel 中的 Url 下载图片
时隔一个月,突然有了采集图片的机会,又让 sir 有了一点动力。因为 URL 已经通过其他爬虫采集到 excel 工作簿当中,于是 sir 又学习了一下第三方包 openpyxl,之后又开始动手了。
- from urllib import request #导入request函数
- from openpyxl import load_workbook #导入load_workbook函数
- #自定义一个根据url和图片文件名称为参数,自动下载图片的函数
- def downloadImage(imageUrl,imagePath):
- response=request.urlopen(imageUrl)#访问图片地址,获得响应
- imageContents=response.read()#获取图片内容
- f=open(imagePath,'wb')#打开文件
- f.write(imageContents)#写入内容
- f.close#关闭文件
- #打开Excel workbook
- wb=load_workbook('image.xlsx')
- #指定工作表
- ws=wb.active
- #获取单元格内容 从第二行开始 到空白单元格结束
- i=2
- while ws.cell(row=i,column=1).value!=None:
- #生成文件名 A列为文件名称
- Path= str(i-1)+'_'+ws.cell(row=i,column=1).value +'.jpg'
- #获取URL地址 B列为URL地址
- Url=ws.cell(row=i,column=2).value
- #调用函数下载图片
- downloadImage(imageUrl=Url,imagePath=Path) #循环下载图片
- print('已下载第'+str(i-1)+'张高清图片>>>')
- i+=1
因为函数 downloadimage 内部没有添加异常处理,于是碰到 request 失败的时候,脚本就停止不动了。添加了异常处理之后,sir 有发觉下载的速度真的好慢。于是第二天求助了一位相识。
(三)多线程下载图片
这位朋友发了一段代码,让我自己学习。研究之后 sir 发现了,把具体要做的事情,放到多线程下载那个类的内部,就可以使用多线程下载。速度立马快的飞起。30 秒给我下了 2000 多张图片,高达 1G,还好我及时终止了脚本。
同时 Sir 也学到异常处理怎么写,就是在 json 中找到图片地址那个写法一开始令人费解,花了一段时间才明白怎么回事。
- import requests
- import json
- import threading
- Default_Header = {
- #具体请求头自己去弄
- }
- _session=requests.session()
- _session.headers.update(Default_Header)
- #多线程下载
- class myThread(threading.Thread):
- def __init__(self,imgUrl,fname):
- threading.Thread.__init__(self)
- self.imgUrl=imgUrl
- self.fname=fname
- def run(self):
- print("downloading",self.imgUrl)
- download(self.imgUrl,self.fname)
- def download(fileid,type):
- img_url="http://img.hb.aicdn.com/"+fileid
- imgresp=requests.get(img_url)
- byte_img = imgresp.content
- try:
- out = open(type, 'wb')
- out.write(byte_img)
- out.flush()
- out.close()
- except Exception as e:
- print(e)
- if __name__ == "__main__":
- r =_session.get('http://huaban.com/pins/873774526/?xxxxxx')
- url=json.loads(r.text)
- urlList=url['pin']['board']['pins']
- for i in urlList:
- key=i['file']['key']
- print(key)
- #download(key,key+'.jpg')
- myThread(key,key+'.jpg').start()
(四)多线程采集改造
- from urllib import request
- from bs4 import BeautifulSoup
- from openpyxl import Workbook
- import threading
- import re
- import time
- #功能函数
- def get_title(url):
- global n #变量全局化
- global pageindex #变量全局化
- #global ws #为什么声明与不声明都一样?
- try: #打开网页,保存试卷标题和链接
- r=request.urlopen(url,timeout=10) #打开网页,设置超时 response
- s=r.read() #读取网页源码
- js=s.decode('utf-8') #网页转码
- soup=BeautifulSoup(js,'lxml') #网页解析
- #正则查找子节点
- for a in soup.find_all('a',href=re.compile(r'http://blog.sina.com.cn/s/blog')):
- n+=1 #计数
- ws.cell(row=n+1,column=1).value=n #写入序号
- ws.cell(row=n+1,column=2).value=a.string #写入标题
- ws.cell(row=n+1,column=3).value=a.get('href') #写入链接
- print("download succeed >>>>"+url+'\n') #正常输出
- except Exception as e:
- print("download failed >>>>"+url+'\n') #异常输出
- if __name__ =='__main__':#主线程
- start=time.time() #开始时间
- filename='多线程爬取启迪慧想试题标题与链接.xlsx' #Excel文件名
- threads=[] #新建线程列表
- wb=Workbook() #新建工作簿
- ws=wb.active #活动工作表
- n=0 #初始化计数
- #输入表头
- ws.cell(row=n+1,column=1).value='序号'
- ws.cell(row=n+1,column=2).value='标题'
- ws.cell(row=n+1,column=3).value='链接'
- #设置起止页码
- pageindex=1
- pagecount=10
- #filename=str(pagecount)+filename
- while pageindex<=pagecount:
- url=u'http://blog.sina.com.cn/s/articlelist_xxxxxxxxx_0_'+str(pageindex)+'.html'
- t=threading.Thread(target=get_title,args=(url,))#添加子线程
- threads.append(t) #加入线程列表
- pageindex+=1 #下一页
- for t in threads:
- t.setDaemon(True) #守护线程 必须在start()之前
- t.start() #开始线程
- #若t.join()放此处 则变成单线程
- for t in threads:
- t.join() #线程等待 主线程必须在子线程执行结束之后 才能继续
- wb.save(filename=filename) #保存工作簿
- end=time.time() #结束时间
- print('Usedtime %f seconds!' % (end-start) +'\n') #输出耗时!
python 学习笔记 (一)
来源: http://www.bubuko.com/infodetail-2152683.html