import requests,re #导入requests与正则表达式模块 from multiprocessing import Pool#导入多线程模块 #定义一个可以重复调用的函数,这个函数实现的功能是获取每个新闻横框的内容 def get_new(url):#def 是函数前缀 get_new()是自定义函数名 url是自定义参数 html1 = requests.get(url)#对传入 get_new()的url进行请求,利用的是requests模块的get函数,因为该网页是get型网页,请求到的内容是响应状态,响应头和响应体 html2 = html1.text#这里我们只取请求内容的响应体 #print(html2) #pattern为自定义对象,这里是我们的正则表达式匹配的内容 pattern='''<div class="media"> <div class="media-body"> <h3 class="list-title text-overflow margin-top-none"> <a href="(.*?)"> (.*?) </a> </h3> <a class="picwraper" href=".*?"> <img class="list-cover lazy" src="(.*?)"> </a> <div class="list-abstract text-muted"> <p>.*?</p> </div> <ul class="list-info list-unstyled list-inline text-muted small"> <li><i class="fa fa-calendar"></i> (.*?)</li> <li><i class="fa fa-eye"></i> (.*?)</li> </ul> </div> </div>''' #对我们前面那个url请求到的请求体进行解析,使用re模块的findall方法,re.S代表可以换行匹配 news = re.findall(pattern, html2, re.S) for each in news:#对new对象的内容进行挨个迭代 #这里因为有些新闻没用图片,所以我们需要加一个判断 if '.jpg' not in each[2]:#因为each对象是一个元组,我们通过正则匹配出来的新闻图片排序第三,因此存放图片位置的下标为2 #将each对象实例化成字典对象,方便我们进行索引查询 yield { 'url': 'http://news.sise.edu.cn' + each[0], 'title': each[1], 'date': each[3], 'scannum': each[4] } else: yield { 'url': 'http://news.sise.edu.cn' + each[0], 'title': each[1], 'image': 'http://news.sise.edu.cn' + each[2], 'date': each[3], 'scannum': each[4] } #这个函数作用为对图片进行下载 def dowmload(image,filename,path):#需要传入的参数为新闻图片的链接,我们需要命名的名字,文件存放路径 html=requests.get(image)#请求图片链接 html=html.content#这里我们只需要请求的主体内容,即图片的内容(二进制格式) # 进行文件操作open是创建一个文件,'wb'是写入的意思,path+"\%s.jpg"%filename的作用是对图片的路径进行写入, # 例如我想保存一张命名为1.jpg的图片到d盘的1文件夹,其路径为D:/1/1.jpg with open(path+"\%s.jpg"%filename,'wb') as file: file.write(html)#将我们请求到的图片的内容(二进制格式)写入文件中,并保存 #这是一个主函数,主要作用是用于集合我们的所有调用方法 def main(page):#这里传入的page为我们需要爬取的页数 url = 'http://news.sise.edu.cn/cms/news/2/p/' + str(page) + '.html'#我们需要爬取的新闻网页 for i in get_new(url):#使用get_new()对url我们需要的内容抓取,遍历我们的实例化后的字典 try:#try是为了避免程序报错导致程序崩溃,这里可以理解为尝试进行下面的命令,如果程序崩溃,就用except的方法 dowmload(i['image'], i['date'], 'D:\\1\\na\\')#使用download()函数对我们从get_new()拿到的内容进行操作,i['image']保存的是新闻的链接,i['date']是新闻的发布日期,这里我们用来做图片的标题,当然也可以换成其他内容作为标题,'D:\\1\\na\\'为文件的前缀路径,级在d盘下的1文件夹的na文件夹,D:\\1\\na\\原本为D:\1\na\,这里加了\是对前面的\进行转义,避免程序把我们前面的\认为是正则表达式中的\ except:#如果上面的程序出错就进行下面的操作 continue#跳出本次循环,进行下一个循环 if __name__ == '__main__':#当.py文件被直接运行时,if __name__ == '__main__'之下的代码块将被运行;当.py文件以模块形式被导入时,if __name__ == '__main__'之下的代码块不被运行。通俗理解便是假如你叫小明.py,在朋友眼中,你是小明(__name__ == '小明');在你自己眼中,你是你自己(__name__ == '__main__'),这样的作用是避免自己调用自己时,程序执行两次 pool = Pool()#定义一个多线程任务 #map函数:将第一个参数作为方法,第二个参数作为方法的参数,例如我有一个计算器(第一个参数(方法)),但是我需要计算10个等式(第二个参数:方法的参数),map函数作用就是使用计算器对每个等式进行计算(迭代),把10个结果返回出来 pool.map(main, [page for page in range(0,10)])#使用这个多线程对map(main, [page for page in range(0,10)])函数进行操作,main我们爬取每一页图片的方法[page for page in range(0,10)] 可以理解为页码是来自于for page in range(0,10)里面的,range(0,10)是一个0到9的队列,for page in是将队列的值挨个提取(迭代) # #下面是自定义输入页面 # newpage=int(input("请输入需要爬取的新闻图片页数:")) # pool = Pool() # pool.map(main, [page for page in range(0, newpage)])
简单多线程爬取新闻图片
猜你喜欢
转载自blog.csdn.net/qq_41686130/article/details/79951435
今日推荐
周排行