设为首页收藏本站

Crossin的编程教室

 找回密码
 立即加入
查看: 24686|回复: 18
打印 上一主题 下一主题

抓取美女图片的爬虫小程序

[复制链接]

1

主题

0

好友

50

积分

注册会员

Rank: 2

跳转到指定楼层
楼主
发表于 2014-6-27 18:51:22 |只看该作者 |倒序浏览
一个python爬虫小程序,爬的是www.22mm.cc里面的美女图片,该如何把它改成多线程呢??
  1. #!/usr/bin/env python
  2. #coding:UTF-8
  3. import urllib
  4. import re
  5. import os
  6. import os.path

  7. index=0
  8. #抓取页面的函数
  9. def getPage(url):
  10.         page=urllib.urlopen(url).read()
  11.         return page

  12. #抓取首页美女分类的链接信息
  13. def getSortLinkInfo(html):
  14.         patt='<a href="/[^\s]+?\.html" title="[^\s]+?"'
  15.         regex=re.compile(patt)
  16.         linkInfo=re.findall(regex,html)
  17.         links={}
  18.         for i in linkInfo:
  19.                 #links.append('http://www.22mm.cc'+i.split('"')[1])
  20.                 links['http://www.22mm.cc'+i.split('"')[1]]=i.split('"')[3]
  21.         return links        #links是有效链接的列表

  22. #获取特定美女页面中的链接信息
  23. def getBeautyLinkInfo(link):
  24.         page=getPage(link)
  25.         patt='<a href=\'[^\s]+?-\d+?\.html\'>\d+?</a>'
  26.         regex=re.compile(patt)
  27.         lastLink=re.findall(regex,page)
  28.         if len(lastLink)>0:
  29.                 lastLink=lastLink[-1].split("'")[1]
  30.         return lastLink                #lastLink是最后一个美女页面的相对路径

  31. #提取最终美女图片的链接
  32. def getImgLinks(lastLink):
  33.         page=getPage(lastLink)
  34.         patt='arrayImg\[0\]="(http://[^\s]+?\.jpg)"'
  35.         regex=re.compile(patt)
  36.         imgLinks=re.findall(regex,page)
  37.         return imgLinks     #imgLinks是有效的图片链接的列表

  38. #下载并且保存图片
  39. def saveImg(imgLinks,dirname):
  40.         global index
  41.         path=unicode('D:\\pics\\'+dirname,'utf8')
  42.         os.mkdir('%s' %(path))
  43.         dirname=dirname.decode('utf8')
  44.         for i in imgLinks:
  45.                 urllib.urlretrieve(i,'D:\\pics\%s\%d.jpg' % (dirname,index))
  46.                 print '%s has been downloaded and saved successfully.'%(i)
  47.                 index+=1

  48. indexURL='http://www.22mm.cc'

  49. def start():
  50.         homePage=getPage(indexURL)
  51.         links=getSortLinkInfo(homePage)
  52.         for i in links:
  53.                 #dirname=unicode('D:\\pics\\'+links[i],'utf8')
  54.                 #os.mkdir('%s' %(dirname))
  55.                 dirname=links[i]
  56.                 relPath=getBeautyLinkInfo(i)       
  57.                 if len(relPath)>0:
  58.                         lastLink='http://www.22mm.cc/mm/'+i.split("/")[4]+'/'+relPath
  59.                         tempLinks=getImgLinks(lastLink)
  60.                         imgLinks=[]
  61.                         for j in tempLinks:
  62.                                 imgLinks.append(re.sub('big','pic',j))
  63.                         saveImg(imgLinks,dirname)
  64.                     
  65.                         
  66. start()
复制代码
回复

使用道具 举报

174

主题

45

好友

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

沙发
发表于 2014-6-28 16:57:06 |只看该作者
这个程序有意思
去看一下 thread 模块相关的用法
#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

1

主题

0

好友

50

积分

注册会员

Rank: 2

板凳
发表于 2014-6-30 23:19:22 |只看该作者
修改了一下,之前的只能抓取首页的图片,下面这个应该能爬取全站的
  1. #!usr/bin/env python
  2. #coding:UTF-8
  3. import urllib2
  4. import urllib
  5. import re
  6. import os

  7. # 获取页面的html
  8. def get_page(url):
  9.         req=urllib2.Request(url)
  10.         try:
  11.                 html=urllib2.urlopen(req).read()
  12.                 return html
  13.         except urllib2.URLError,e:
  14.                 if e.code==404:
  15.                         return False

  16. #获取美女图片的四个分类链接
  17. def get_fen_lei_link(html):
  18.         patt='<a href="/mm/[^\s]+?/" >'
  19.         regex=re.compile(patt)
  20.         fen_lei_link=[]
  21.         temp_link=re.findall(regex,html)[0:4]
  22.         for link in temp_link:
  23.                 fen_lei_link.append('http://www.22mm.cc'+link.split('"')[1])
  24.         return fen_lei_link

  25. #获取套图的链接
  26. def get_taotu_link(specific_page):
  27.         global taotu_links
  28.         taotu_links={}
  29.         patt='<a href="/[^\s]+?\.html" title=".+?"'
  30.         regex=re.compile(patt)
  31.         link_info=re.findall(regex,specific_page)
  32.         for i in link_info:
  33.                 taotu_links['http://www.22mm.cc'+i.split('"')[1]]=i.split('"')[3]

  34. #获取套图页面中指向最后一个图片的链接
  35. def get_taotu_last_link(taotu_link):
  36.         taotu_page=get_page(taotu_link)
  37.         patt='<a href=\'[^\s]+?-\d+?\.html\'>\d+?</a>'
  38.         regex=re.compile(patt)
  39.         taotu_last_link=re.findall(regex,taotu_page)[-1].split("'")[1]
  40.         return taotu_last_link

  41. #获取暂时的图片链接
  42. def get_temp_image_link(taotu_last_link):
  43.         taotu_last_page=get_page(taotu_last_link)
  44.         patt=patt='arrayImg\[\d\]="(http://[^\s]+?\.jpg)"'
  45.         regex=re.compile(patt)
  46.         temp_image_link=re.findall(regex,taotu_last_page)
  47.         return temp_image_link

  48. #将图片下载并且保存到D盘的pic文件夹中
  49. def save_image(image_links,dirname):
  50.         global index
  51.         path=unicode('D:\\pic\\'+dirname,'utf8')
  52.         os.mkdir('%s' %(path))
  53.         dirname=dirname.decode('utf8')
  54.         for img_link in image_links:
  55.                 urllib.urlretrieve(img_link,'D:\\pic\%s\%d.jpg' % (dirname,index))
  56.                 print '%s has been downloaded and saved successfully.'%(img_link)
  57.                 index+=1

  58. def start():
  59.         print 'Waiting............'
  60.         url='http://www.22mm.cc'
  61.         html=get_page(url)
  62.         fen_lei_link=get_fen_lei_link(html)
  63.         for link in fen_lei_link:
  64.                 temp_link=link
  65.                 page_index=1        #page_index是页面索引
  66.                 specific_page=get_page(link)
  67.                 get_taotu_link(specific_page)
  68.                 while page_index<4:        #套图的数目很多,暂时只抓取每个分类的前三页图片
  69.                         if page_index==1:
  70.                                 specific_page=get_page(link)
  71.                                 get_taotu_link(specific_page)
  72.                         else:
  73.                                 link=temp_link+'index_%d.html' %(page_index)
  74.                                 specific_page=get_page(link)
  75.                                 if not specific_page:
  76.                                         break
  77.                                 else:
  78.                                         get_taotu_link(specific_page)
  79.                         for key in taotu_links:
  80.                                 dirname=taotu_links[key]
  81.                                 temp_taotu_last_link=get_taotu_last_link(key)
  82.                                 taotu_last_link='http://www.22mm.cc/mm/'+key.split("/")[4]+'/'+temp_taotu_last_link
  83.                                 temp_image_link=get_temp_image_link(taotu_last_link)
  84.                                 image_links=[]
  85.                                 for each in temp_image_link:
  86.                                         image_links.append(re.sub('big','pic',each))
  87.                                 save_image(image_links,dirname)
  88.                         page_index+=1

  89. #links是存储套图链接信息的字典
  90. taotu_links={}
  91. #index是图片名称的索引
  92. index=0
  93. start()
复制代码
对于Python的多线程,我有好些疑问,搜索了也没得到满意的答案
1.一个进程里面同一时刻只能运行一个线程么?
2.倘若1成立,那么sleep()在实际的应用程序中不是反而拉低了效率?
提了两个很菜的问题,希望crossin先生看到了能顺手解答一下,多谢
回复

使用道具 举报

174

主题

45

好友

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

地板
发表于 2014-7-1 11:50:26 |只看该作者
creek 发表于 2014-6-30 23:19
修改了一下,之前的只能抓取首页的图片,下面这个应该能爬取全站的对于Python的多线程,我有好些疑问,搜索 ...

是的。如果cpu只能同时执行一个进程,那么多线程的计算没有什么好处,甚至还耽误了线程切换的时间。
但是多线程可以避免一个线程被阻塞住,导致其他任务无法进行的情况,这在有网络请求或者文件读写的时候很有用。相当于把等待对方服务器响应和下载的时间节省了下来。
另外,我不是很确定,多核cpu是否可以并行多个python线程。
#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

0

主题

0

好友

558

积分

高级会员

Rank: 4

5#
发表于 2014-9-22 19:07:59 |只看该作者
楼主,我复制了你的改进后的代码,运行的时候只是在命令行输出了wait...其他什么都没有,D盘没有图片。于是我又在D盘下手动新建一个文件夹,名字是pic,再次运行,可以了,但是下载了两组图片后,大概有十多张,就报错停止了,说是下表越界。重新运行,又是只是在命令行输出了wait...其他什么都没有。这是怎么回事啊?
学习,纯粹。
回复

使用道具 举报

0

主题

1

好友

38

积分

新手上路

Rank: 1

6#
发表于 2015-9-7 13:13:52 |只看该作者
@crossin先生  我自己也写了一个抓取图片的脚本,但是在下载图片到电脑的时候发生urllib.error.ContentTooShortError: <urlopen error retrieval incomplete: got only 36211 out of 508217 bytes>的错误,再次执行,却没有任何问题,怀疑是不是和网络有关?由于网速较慢,导致下载图片到内存中的部分较少或者内存占用率较高导致?有没有什么办法能够避免这种错误发生?
回复

使用道具 举报

174

主题

45

好友

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

7#
发表于 2015-9-8 19:16:59 |只看该作者
小燕smile 发表于 2015-9-7 13:13
@crossin先生  我自己也写了一个抓取图片的脚本,但是在下载图片到电脑的时候发生urllib.error.ContentTooS ...

似乎只是网络不好,没能一次下载成功。
避免发生就是做异常处理,错误的情况下自动重新下载
#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

0

主题

0

好友

4

积分

新手上路

Rank: 1

8#
发表于 2016-3-13 21:45:57 |只看该作者
我是新手 请问这些代码是在哪运行的? 是cmd里的python吗······
回复

使用道具 举报

174

主题

45

好友

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

9#
发表于 2016-3-14 12:30:18 |只看该作者
airabout 发表于 2016-3-13 21:45
我是新手 请问这些代码是在哪运行的? 是cmd里的python吗······

先保存在文件里,然后在cmd下用 python xxx.py 这样的命令来执行。或者放在开发工具里执行
#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

0

主题

1

好友

38

积分

新手上路

Rank: 1

10#
发表于 2016-4-13 16:25:55 |只看该作者
不清楚之前该网站的源代码怎么写的,但是目前该网站很多地方貌似做了改版,没有实际测试lz的代码,估计已经不能用了吧!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即加入

QQ|手机版|Archiver|Crossin的编程教室 ( 苏ICP备15063769号  

GMT+8, 2024-12-4 16:12 , Processed in 0.016357 second(s), 21 queries .

Powered by Discuz! X2.5

© 2001-2012 Comsenz Inc.

回顶部