[关闭]
@FadeTrack 2015-08-31T06:51:31.000000Z 字数 4339 阅读 2363

Python 爬虫入门《中》

Python 爬虫


承上启下

上篇已经讲到了简单的爬虫的一些相关的东西,模块学习,这篇就从最基本的"爬虫"开始,一句一句的阅读一个炒鸡简单的“爬虫”。

蠕动的小家伙

  1. import urllib.request
  2. import os
  3. import re
  4. # 未写
  5. def proxy_open():
  6. # 安装代理 步骤
  7. # 1. 选择代理
  8. # 2. 建立代理
  9. # 3. 安装代理
  10. pass
  11. def save_pic(url,filename):
  12. req = urllib.request.Request(url)
  13. req.add_header('User-Agent','Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.152 Safari/537.36')
  14. try:
  15. proxy_open()
  16. response = urllib.request.urlopen(req)
  17. except urllib.error.HTTPError:
  18. return
  19. pic = response.read()
  20. if len(pic) == 0:
  21. print('图片不存在')
  22. return
  23. f = open(filename,'wb')
  24. f.write(pic)
  25. f.close()
  26. def find_pic(html):
  27. pic_list = []
  28. a = html.find('<div class=\"postContent\">')
  29. end = html.find('</p>',a)
  30. while True:
  31. b = html.find('src="',a)
  32. if b > end:
  33. break
  34. b += 5;
  35. a = html.find('"',b)
  36. pic_list.append(html[b:a])
  37. return pic_list
  38. def get_pic(url,count):
  39. req = urllib.request.Request(url)
  40. req.add_header('User-Agent','Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.152 Safari/537.36')
  41. response = urllib.request.urlopen(req)
  42. html = response.read()
  43. html = html.decode('gbk')
  44. if re.search(r'很抱歉!没有找到符合条件的页面哦',html) != None:
  45. print('页面无法访问')
  46. return
  47. # print(str(html))
  48. # 找到图片链
  49. pic_list = find_pic(html)
  50. if len(pic_list) == 0:
  51. return
  52. # 保存图片
  53. index = 0
  54. for each in pic_list:
  55. print(each)
  56. filename = './OOXX/' + str(count) + '_' + str(index) + '.jpg'
  57. save_pic(each,filename)
  58. index += 1
  59. def download_mm(folder = 'OOXX',pages = 100):
  60. try:
  61. os.mkdir(folder)
  62. # os.chdir(folder)
  63. except FileExistsError:
  64. pass
  65. url_module = 'http://www.meizitu.com/a/%d.html'
  66. count = 34
  67. while True:
  68. if count >= pages:
  69. break
  70. url = url_module.replace('%d',str(count))
  71. print(url)
  72. get_pic(url,count)
  73. count += 1
  74. if __name__ == '__main__':
  75. download_mm()

解释

这段代码我曾经发出来过,是一个很简单的,甚至算不上“爬虫”的“爬虫”。

刚刚开始读Python代码的时候,其实我是非常不适应的,我是属于典型的windows程序员,很不习惯这种小写加上下划线的命名规范,当然,到现在为止,我依旧不适应这种写法,也间接的说明了我的英语很烂的缘故吧。

废话不多了,首先开始读。

c 的 main() 一样 ,python 也有一个入口点,就是

  1. if __name__ == '__main__':
  2. download_mm()

一般是采用这种形式来说明程序的入口。

可以看到这里调用了一个函数 download_mm , 这个是属于个人的封装习惯了,不同的人对于函数的封装习惯略有区别。

  1. def download_mm(folder = 'OOXX',pages = 100):

函数声明部分说明了,这个函数是有两个可选的默认参数的,由于我也就忘记了这个默认参数的习惯,所以 我遵循 c++ 的标准,从最右边开始,往左,但是 python 这么灵活的语言中应该是没有这个限制的。

  1. try:
  2. os.mkdir(folder)
  3. # os.chdir(folder)
  4. except FileExistsError:
  5. pass

使用了一个叫做 os 的模块,可以通过帮助文档,这个 模块的主要作用是和计算机的文件系统打交道的。

其实我觉得这种说法是片面的,感觉就是和文件及文件夹相关的操作。

这里是创建了一个目录,之后改变了工作目录,其实在帮助文档说的非常详细了,
我大概也知道有很多和我一样苦逼的自学朋友们英语没有那么溜,我这里也顺便给大家推荐一个小软件 QTranslate ,小巧便捷,支持几个在线词库,还不错。

接着是一个异常处理,如果文件夹存在那么创建的话就会报出一个异常,我们接收异常之后略过就好了,因为本来的目的就创建文件夹。

仔细看了之后 觉得这个 os.chdir(folder) 在这里有一些多余,毕竟是默认的相对路径且不支持指定路径,这里不要也是成立的。(未验证)

  1. url_module = 'http://www.meizitu.com/a/%d.html'
  2. count = 34
  3. while True:
  4. if count >= pages:
  5. break
  6. url = url_module.replace('%d',str(count))
  7. print(url)
  8. # 获取图片
  9. get_pic(url,count)
  10. count += 1

后面是一个简单的循环,为了匹配这个网页的规则,也就是说明了爬虫是具有一定规则性的,当然你如果能支持非常多的规则的话,应该能爬到不少东西,我这里充其量算是一个精确搜索的爬虫。

接下来,我自己吐槽一下我自己的这个地方的字符串算法,应该是有更好的办法写的,各位看官可以下去自己测试,就是 replace 的地方,之后把生成的链接和和count传入了 get_pic 函数,传入 count 的目的是给生成的图片命名。

爬虫第二个比较关键的函数就是这个获取图片了。

  1. def get_pic(url,count):
  2. req = urllib.request.Request(url)
  3. req.add_header('User-Agent','Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.152 Safari/537.36')
  4. response = urllib.request.urlopen(req)
  5. html = response.read()
  6. html = html.decode('gbk')
  7. if re.search(r'很抱歉!没有找到符合条件的页面哦',html) != None:
  8. print('页面无法访问')
  9. return
  10. # print(str(html))
  11. # 找到图片链
  12. pic_list = find_pic(html)
  13. if len(pic_list) == 0:
  14. return
  15. # 保存图片
  16. index = 0
  17. for each in pic_list:
  18. print(each)
  19. filename = './OOXX/' + str(count) + '_' + str(index) + '.jpg'
  20. save_pic(each,filename)
  21. index += 1

先说一下它的写法。

这里使用了我们上篇说到的 urllib.request 模块,用来获取网页的源代码。

获取到源码之后 传入了 find_pic 函数,这个函数的目的是 找到源码中的,我们需要的东西,即图片的链接。

  1. def find_pic(html):
  2. pic_list = []
  3. a = html.find('<div class=\"postContent\">')
  4. end = html.find('</p>',a)
  5. while True:
  6. b = html.find('src="',a)
  7. if b > end:
  8. break
  9. b += 5;
  10. a = html.find('"',b)
  11. pic_list.append(html[b:a])
  12. return pic_list

使用的是最基本的字符串查找算法,如果这里使用正则可以几句代码就搞定,各位看官下去可以自己尝试写成正则的。
正则模块是 re ,可以自己学习这个模块的使用方法。

之后将这个存放图片链接列表遍历一下,保存到本地,调用了 save_pic

这个函数的写法如下:

  1. def save_pic(url,filename):
  2. req = urllib.request.Request(url)
  3. req.add_header('User-Agent','Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.152 Safari/537.36')
  4. try:
  5. proxy_open()
  6. response = urllib.request.urlopen(req)
  7. except urllib.error.HTTPError:
  8. return
  9. pic = response.read()
  10. if len(pic) == 0:
  11. print('图片不存在')
  12. return
  13. f = open(filename,'wb')
  14. f.write(pic)
  15. f.close()

这里使用了以前的方法,使用 openwriteclose 来保存文件。这里需要注意的一点是, 写入文件之后一定要立马调用 close 方法,否则可能出现一些很奇怪的事情,例如文件写入乱码和失败,至于为什么会出现这种问题,各位读者请自己思考,为什么留下这些问题是为了给读者一些思考的空间。

不得不提的是,这里还有这么个东西可以用来保存文件:

  1. urllib.request.urlretrieve(url, filename=None, reporthook=None, data=None)

到这里基本流程就全部解释完毕了,关于代理和多线程处理,会在下一篇中继续跟进。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注