《零基础入门学习Python》第056讲:论一只爬虫的自我修养4:网络爬图

news/2024/12/22 9:25:17/

今天我们结合前面学习的知识,进行一个实例,从网络上下载图片,话说我们平时闲来无事会上煎蛋网看看新鲜事,那么,熟悉煎蛋网的朋友一定知道,这里有一个 随手拍 的栏目,我们今天就来写一个爬虫,自动抓取每天更新的 随手拍。

要写爬虫,首先要做的第一件事就是踩点,主动发现网页之间的规律,还有图片链接之间有什么规律,例如说,该网站的链接形式为:http://jandan.net/ooxx/page-‘页码数’#comments,(页码数应该小于等于当天的页码数(即目前最大页码数)),

1.那我们怎样获取目前最大的页码数呢(最新页码),我们在页码[77]这个位置点击右键,审查元素,看到了:<span class="current-comment-page">[77]</span>

我们完全可以通过搜索 current-comment-page 在后面偏移 3 位就可以得到 77 这个最新的页面,因为你不能去输入一个具体的数字,因为这里的数字每天都会改变。

2.我们在图片的位置点击右键,审查元素,发现了图片的地址,都是来自于新浪,然后都在 img 标签里,我们就可以使用 img src 作为关键词来进行查找,搜索到了图片的地址就可以参照我们之前下载一只猫的例子了。把下面图片的地址用 urlopen() 打开,然后将其 save 到一个文件里去(二进制),就可以了。

<img src="http://ww3.sinaimg.cn/mw600/006XNEY7gy1fy62ba9d6cj30u00u0x6p.jpg" style="max-width: 480px; max-height: 750px;">

我们弄清楚了以上几点,就可以开始写我们的爬虫程序啦.....

(我们抓取前10页的图片,保存到指定的本地文件夹中)

下面是老师讲的代码:

 
  1. #从煎蛋网的随手拍栏目下载图片

  2. import urllib.request

  3. import os

  4. import random

  5. def url_open(url):

  6. req = urllib.request.Request(url)

  7. req.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.65 Safari/537.36')

  8. #使用代理(就加入下面五行)

  9. #proxies = ['119.6.144.70:81', '111.1.36.9:80', '203.144.144.162:8080']

  10. #proxy = random.choice(proxies)

  11. #proxy_support = urllib.request.ProxyHandler({'http':proxy})

  12. #opener = urllib.request.build_opener(proxy_support)

  13. #urllib.request.install_opener(opener)

  14. response = urllib.request.urlopen(url)

  15. html = response.read()

  16. return html

  17. def get_page(url): #得到最新页面的页码数

  18. html = url_open(url)

  19. html = html.decode('utf-8') #因为要以字符串的形式查找,所以要 decode

  20. #然后就是查找 html 中的 'current-comment-page'

  21. a = html.find( 'current-comment-page') + 23 #加上 23 位偏移就刚到到页码数的第一位数字

  22. b = html.find(']', a) #找到 a 位置之后的第一个方括号所在位置的索引坐标

  23. return html[a : b] #这就是最新的页码数啦

  24. def find_imgs(url): #给一个页面的链接,返回所有图片地址组成的列表

  25. html = url_open(url).decode('utf-8')

  26. img_addrs = [] #声明一个保存图片地址的列表

  27. #查找图片地址

  28. a = html.find('img src=')

  29. while a != -1:

  30. b = html.find('.jpg', a, a+255) #在 a 到 a+255 区间找 '.jpg',防止有不是 '.jpg' 格式的图片

  31. #如果 b 找不到,b 就返回 -1

  32. if b != -1:

  33. img_addrs.append(html[a+9: b+4])

  34. else:

  35. b = a + 9

  36. a = html.find('img src=', b)

  37. return img_addrs

  38. def save_imgs(folder, img_addrs):

  39. for each in img_addrs:

  40. filename = each.split('/')[-1]

  41. with open(filename, 'wb') as f:

  42. img = url_open(each)

  43. f.write(img)

  44. def download_figures(folder = 'figures', page = 10):

  45. os.mkdir(folder) #创建文件夹

  46. os.chdir(folder)

  47. url = "http://jandan.net/ooxx/" #随手拍栏目的链接,也是最新页面的链接

  48. page_num = int(get_page(url)) #得到最新页面的页码数

  49. for i in range(page):

  50. page_url = url + 'page-' + str(page_num) + '#comments' #得到要爬取的页面的链接

  51. print(page_url)

  52. img_addrs = find_imgs(page_url) #得到页面所有图片的地址,保存为列表

  53. save_imgs(folder, img_addrs) #保存图片到本地文件夹

  54. page_num -= 1 #逐步找到前几个页面

  55. if __name__ == '__main__':

  56. download_figures()

但是现在,煎蛋网用这段代码是无法实现的了,主要问题在于 没有办法爬取到 .jpg,这是因为这个网站已经被加密了。

怎样判断一个网站被加密了,就是

使用urllib.urlopen导出html文本和审查元素中相应字段对不上。

以后你会发现对不上是常态,一般是JS加密的  可以说大一点的网站这些信息都会对不上。

那怎么解决呢?

目前我只用的一种方法就是:使用selenium爬取js加密的网页

需要详细讲解的可以查看:python使用selenium爬取js加密的网页

所以呢,我的代码就是下面这样子了:

 
  1. #从加密的煎蛋网的随手拍栏目下载图片

  2. import os

  3. from selenium import webdriver

  4. import urllib.request

  5. def url_open(url): #返回普通不加密网页的源码(速度快)

  6. req = urllib.request.Request(url)

  7. req.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36')

  8. response = urllib.request.urlopen(url)

  9. html = response.read()

  10. return html

  11. def url_open_jm(url): #返回加密网页的源码(速度慢)

  12. chrome = webdriver.Chrome()

  13. chrome.get(url)

  14. html = chrome.page_source

  15. return html #返回的就是字符串

  16. '''

  17. def get_page(url): #得到最新页面的页码数(可以使用不加密读码得到,为了加快速度)

  18. html = url_open(url)

  19. #然后就是查找 html 中的 'current-comment-page'

  20. a = html.find( 'current-comment-page') + 23 #加上 23 位偏移就刚到到页码数的第一位数字

  21. b = html.find(']', a) #找到 a 位置之后的第一个方括号所在位置的索引坐标

  22. return html[a : b] #这就是最新的页码数啦

  23. '''

  24. def get_page(url): #得到最新页面的页码数

  25. html = url_open(url)

  26. html = html.decode('utf-8') #因为要以字符串的形式查找,所以要 decode

  27. #然后就是查找 html 中的 'current-comment-page'

  28. a = html.find( 'current-comment-page') + 23 #加上 23 位偏移就刚到到页码数的第一位数字

  29. b = html.find(']', a) #找到 a 位置之后的第一个方括号所在位置的索引坐标

  30. return html[a : b] #这就是最新的页码数啦

  31. def find_imgs(url): #给一个页面的链接,返回所有图片地址组成的列表

  32. html = url_open_jm(url) #这个必须使用加密打开的方式

  33. img_addrs = [] #声明一个保存图片地址的列表

  34. #查找图片地址

  35. #加密的网页破解后得到的图像在这里:

  36. #<img src="http://ww3.sinaimg.cn/mw600/006XNEY7gy1fy66dacugfj30qh0zkdhu.jpg"

  37. #所以要先找jpg,然后找img src=

  38. a = html.find('.jpg')

  39. while a != -1:

  40. b = html.rfind('img src=', a-100, a) #在 a-100 到 a区间找 'img src=',必须反向查找

  41. #如果 b 找不到,b 就返回 -1

  42. if b != -1:

  43. img_addrs.append(html[b+9: a+4])

  44. a = html.find('.jpg', a+4)

  45. for each in img_addrs:

  46. print(each)

  47. return img_addrs

  48. def save_imgs(folder, img_addrs):

  49. for each in img_addrs:

  50. filename = each.split('/')[-1]

  51. with open(filename, 'wb') as f:

  52. img = url_open(each)

  53. f.write(img)

  54. def download_figures(folder = 'figures', page = 2):

  55. os.mkdir(folder) #创建文件夹

  56. os.chdir(folder)

  57. url = "http://jandan.net/ooxx/" #随手拍栏目的链接,也是最新页面的链接

  58. page_num = int(get_page(url)) #得到最新页面的页码数

  59. for i in range(page):

  60. page_url = url + 'page-' + str(page_num) + '#comments' #得到要爬取的页面的链接

  61. print(page_url)

  62. img_addrs = find_imgs(page_url) #得到页面所有图片的地址,保存为列表

  63. save_imgs(folder, img_addrs) #保存图片到本地文件夹

  64. page_num -= 1 #逐步找到前几个页面

  65. if __name__ == '__main__':

  66. download_figures()

完美实现目标,只不过selenium 的速度是真的慢,以后如果有更好的办法,会继续改进的,也希望大家多多批评指导。


http://www.ppmy.cn/news/971759.html

相关文章

sqlite3 插入数据

文章目录 需求&#xff0c;操作1.进入sqlite终端2.打开数据库3.执行插入语句。4.查看是否成功 最近有项目在用sqlite3&#xff0c;这个嵌入式数据库&#xff0c;不是很熟练&#xff0c;连个插入数据的语句都得百度哈哈。 记录下&#xff0c;加深记忆&#xff0c;给同样小白的人…

00_ubuntu_开发环境的搭建

ubuntu 的版本22.04 2023-07-21 1.卸载firefox dpkg --get-selections |grep firefox // 查看安装包的信息 sudo apt-get purge firefox firefox-locale-en firefox-locale-zh-hans // 卸载相应的包 2.下载google安装包并安装 wget https://dl.google.com/linux/direct/goo…

设计模式再探——状态模式

目录 一、背景介绍二、思路&方案三、过程1.状态模式简介2.状态模式的类图3.状态模式代码4.状态模式还可以优化的地方5.状态模式的项目实战&#xff0c;优化后 四、总结五、升华 一、背景介绍 最近产品中有这样的业务需求&#xff0c;不同时间(这里不是活动的执行时间&…

视频特效软件有哪些?这些软件值得一试

大家平常在制作视频时&#xff0c;经常需要将多个视频拼接&#xff0c;但是如果两个视频中间没有什么转场过渡的话&#xff0c;会显得很单调。我们可以增加一些转场、音乐、特效&#xff0c;这样整支视频看起来效果会好很多。讲到视频特效&#xff0c;可能有些小伙伴会觉得它很…

如何给视频添加特效?快速制作特效视频

如何给视频添加特效&#xff1f;现如今几乎我们人人每天都在与短视频打交道&#xff0c;有些人在日常的生活中也会剪辑一些短视频。其实剪辑短视频并没有你想象中的那么困难。只是需要找到一款合适的软件就可以很快完成。在短视频剪辑中就有需要给短视频添加特效的操作&#xf…

【软件工程中的各种图】

1、用例图&#xff08;use case diagrams&#xff09; 【概念】描述用户需求&#xff0c;从用户的角度描述系统的功能 【描述方式】椭圆表示某个用例&#xff1b;人形符号表示角色 【目的】帮组开发团队以一种可视化的方式理解系统的功能需求 【用例图】 2、静态图(Static …

基于深度学习的高精度六类海船检测识别系统(PyTorch+Pyside6+YOLOv5模型)

摘要&#xff1a;基于深度学习的高精度六类海船检测识别系统可用于日常生活中检测与定位海船目标&#xff08;散装货船&#xff08;bulk cargo carrier&#xff09;、集装箱船&#xff08;container ship&#xff09;、渔船&#xff08;fishing boat&#xff09;、普通货船&…

SpringBoot实战(二十一)集成 TLog 日志

目录 一、简介二、Maven依赖三、启动类集成四、测试1.服务简介2.服务A代码DemoController.javaDemoFeignClient.java 3.服务B代码4.测试结果 补充一&#xff1a;自定义日志标签模板补充二&#xff1a;SpanId的生成规则补充三&#xff1a;业务标签1.打印入参2.指定连接符3.打印常…