前言

最近在学习python网络爬虫,从爬取图片入手。周末爬取了一个图标网站、果壳、数字尾巴的帖子的图片,现在尝试爬取蚂蜂窝的帖子里的图片。爬取图片仅为个人练习,侵删。

代码框架

import urllib.request
import requests
import re
import osdef getHTML(url):
#获取url指向的网页的html文本 def getImageUrl(html):
#获取html中的图片urldef crawlImage(urlList,savepath='folder'):
#根据图片的url,批量保存图片到本地

1.获取网页html

效仿博主cici_vivi的做法,对蚂蜂窝上随意选取的一个旅游帖,分析它的请求。
Firefox浏览器打开该帖子的url,
按F12“查看元素”,
点击“网络”,
按F5刷新网页,
点击get到的html,
查看Request headers:
该网页完整的Request headers如下:

Host: www.mafengwo.cn
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Referer: http://www.mafengwo.cn/
Connection: keep-alive
Cookie: mfw_uuid=5e15a493-892d-30fd-8f7b-f9b427d723e0; _r=baidu; _rp=a%3A2%3A%7Bs%3A1%3A%22p%22%3Bs%3A18%3A%22www.baidu.com%2Flink%22%3Bs%3A1%3A%22t%22%3Bi%3A1578476691%3B%7D; __jsluid_h=59e2d5954da4576186658ea27c253918; __mfwa=1578476692581.63366.8.1584940053205.1584945013269; __mfwlv=1584940053; __mfwvn=5; __mfwlt=1584945030; uva=s%3A307%3A%22a%3A4%3A%7Bs%3A13%3A%22host_pre_time%22%3Bs%3A10%3A%222020-01-08%22%3Bs%3A2%3A%22lt%22%3Bi%3A1578476693%3Bs%3A10%3A%22last_refer%22%3Bs%3A180%3A%22https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3DzIIeEAiySnkbqfJPHb9C5AVbpHakB4DYW5hweW9_1G6COmUNxEebXW-syv4VC0rFGyXqsd14AbrOhpkq0m-rhQ77RyXSl3CxJFSI0WQeew7%26wd%3D%26eqid%3D8aa9855e0014e809000000065e15a48a%22%3Bs%3A5%3A%22rhost%22%3Bs%3A13%3A%22www.baidu.com%22%3B%7D%22%3B; __mfwurd=a%3A3%3A%7Bs%3A6%3A%22f_time%22%3Bi%3A1578476693%3Bs%3A9%3A%22f_rdomain%22%3Bs%3A13%3A%22www.baidu.com%22%3Bs%3A6%3A%22f_host%22%3Bs%3A3%3A%22www%22%3B%7D; __mfwuuid=5e15a493-892d-30fd-8f7b-f9b427d723e0; Hm_lvt_8288b2ed37e5bc9b4c9f7008798d2de0=1584854152,1584885764,1584928736,1584945013; UM_distinctid=16f848aebd79cd-088c79933954f78-4c302a7b-1fa400-16f848aebd84a5; CNZZDATA30065558=cnzz_eid%3D1650508070-1578473002-null%26ntime%3D1584939849; oad_n=a%3A3%3A%7Bs%3A3%3A%22oid%22%3Bi%3A1029%3Bs%3A2%3A%22dm%22%3Bs%3A15%3A%22www.mafengwo.cn%22%3Bs%3A2%3A%22ft%22%3Bs%3A19%3A%222020-03-22+13%3A15%3A49%22%3B%7D; __mfwc=direct; bottom_ad_status=0; __jsl_clearance=1584945010.161|0|F0uqf9xJ1%2BXv02g3rPjNIDIGtu4%3D; PHPSESSID=d07def41hatb2or2i76ndgi0e7; Hm_lpvt_8288b2ed37e5bc9b4c9f7008798d2de0=1584945030; __mfwb=8d5c8d82f88c.2.direct
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0

作为初学者,我对这些内容的含义自然是一窍不通的。因此,我选择将这些内容一股到都塞到获取网页html代码里的headers字典里:

def getHTML(url):headers = {'Host': 'www.mafengwo.cn','User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0','Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8','Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2','Accept-Encoding': 'gzip, deflate','Referer': 'http://www.mafengwo.cn/','Connection': 'keep-alive','Cookie': 'mfw_uuid=5e15a493-892d-30fd-8f7b-f9b427d723e0; _r=baidu; _rp=a%3A2%3A%7Bs%3A1%3A%22p%22%3Bs%3A18%3A%22www.baidu.com%2Flink%22%3Bs%3A1%3A%22t%22%3Bi%3A1578476691%3B%7D; __jsluid_h=59e2d5954da4576186658ea27c253918; __mfwa=1578476692581.63366.8.1584940053205.1584945013269; __mfwlv=1584940053; __mfwvn=5; __mfwlt=1584945030; uva=s%3A307%3A%22a%3A4%3A%7Bs%3A13%3A%22host_pre_time%22%3Bs%3A10%3A%222020-01-08%22%3Bs%3A2%3A%22lt%22%3Bi%3A1578476693%3Bs%3A10%3A%22last_refer%22%3Bs%3A180%3A%22https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3DzIIeEAiySnkbqfJPHb9C5AVbpHakB4DYW5hweW9_1G6COmUNxEebXW-syv4VC0rFGyXqsd14AbrOhpkq0m-rhQ77RyXSl3CxJFSI0WQeew7%26wd%3D%26eqid%3D8aa9855e0014e809000000065e15a48a%22%3Bs%3A5%3A%22rhost%22%3Bs%3A13%3A%22www.baidu.com%22%3B%7D%22%3B; __mfwurd=a%3A3%3A%7Bs%3A6%3A%22f_time%22%3Bi%3A1578476693%3Bs%3A9%3A%22f_rdomain%22%3Bs%3A13%3A%22www.baidu.com%22%3Bs%3A6%3A%22f_host%22%3Bs%3A3%3A%22www%22%3B%7D; __mfwuuid=5e15a493-892d-30fd-8f7b-f9b427d723e0; Hm_lvt_8288b2ed37e5bc9b4c9f7008798d2de0=1584854152,1584885764,1584928736,1584945013; UM_distinctid=16f848aebd79cd-088c79933954f78-4c302a7b-1fa400-16f848aebd84a5; CNZZDATA30065558=cnzz_eid%3D1650508070-1578473002-null%26ntime%3D1584939849; oad_n=a%3A3%3A%7Bs%3A3%3A%22oid%22%3Bi%3A1029%3Bs%3A2%3A%22dm%22%3Bs%3A15%3A%22www.mafengwo.cn%22%3Bs%3A2%3A%22ft%22%3Bs%3A19%3A%222020-03-22+13%3A15%3A49%22%3B%7D; __mfwc=direct; bottom_ad_status=0; __jsl_clearance=1584945010.161|0|F0uqf9xJ1%2BXv02g3rPjNIDIGtu4%3D; PHPSESSID=d07def41hatb2or2i76ndgi0e7; Hm_lpvt_8288b2ed37e5bc9b4c9f7008798d2de0=1584945030; __mfwb=8d5c8d82f88c.2.direct','Upgrade-Insecure-Requests': '1','Cache-Control': 'max-age=0'}try:html = requests.get(url,headers=headers,timeout=5)html.raise_for_status()html.encoding = 'utf-8' #r.apparent_encodingreturn html.textexcept:return 'something wrong'

成功获得这篇帖子的html文本:

在网上看到的获取网页html的代码中,headers通常只包括‘User-Agent’一项。但是我在实践中发现,仅包括‘User-Agent’一项时抓取蚂蜂窝帖子的html文本会出现http error,无法成功获取html。为了验证headers中哪些内容是必须的,我采取了一个笨方法进行实验:逐一注释掉headers中的项目,直至无法成功获取html。实验发现,headers至少应该包括‘User-Agent’和‘Cookie’两项。‘User-Agent’是不变的,会变的是‘Cookie’,因此将其作为函数参数。改进后的代码是:

def getHTML(url,cookie):headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0','Cookie': cookie}try:html = requests.get(url,headers=headers,timeout=5)html.raise_for_status()html.encoding = 'utf-8'#r.apparent_encodingreturn html.textexcept:return 'something wrong'

2.提取图片url

在这一部分,我的做法是根据html中包含图片的标签的规律,编写相应的正则表达式来有效筛选、提取图片的url。
为此需要首先观察蚂蜂窝帖子html中图片标签的规律,对帖子正文的图片右键“查看元素”:

研究了多张图片后发现,图片的有效url包含在’data-rt-src="'和‘?image…’中,由此编写代码如下:

def getImageUrl(html):
#将html按空格分割并存入一个列表中,然后获取其中的图片urlhtml_splited = re.split(r'\s+',html) #对html文本按空格分割targetURL = [] #用于保存目标url的listfor i in html_splited:if (re.match(r'data-src',i)): #筛选目标url的条件if (re.match(r'.*?png.',i)) or (re.match(r'.*?jpg.',i)) or (re.match(r'.*?jpeg.',i)): #筛选目标url的条件            if(re.match(r'.*?http',i)): #筛选目标url的条件,过滤掉不具有有效路径的图片url                if (re.match(r'.*\?',i)):url = re.search(r'.*src="(.*)\?',i).group(1) #获取图片有效url                else:url = re.search(r'.*src="(.*)"',i).group(1)#url = itargetURL.append(url)print(url)return targetURL

代码返回获得的图片url列表:

3.将图片保存到本地

这一部分代码比较简单,从图片url的列表中,注意打开图片url,然后保存到本地即可。
代码会检查图片格式;用户可以定义保存的相对路径,如无定义,则会新建“folder”文件夹并将图片保存于其中;在保存图片时,图片按数字升序命名。

def crawlImage(urlList,savepath='folder'):
#根据图片的url,批量保存图片到本地count = 1for i in urlList:img_webpage = urllib.request.urlopen(i)img_data = img_webpage.read()pathExist = os.path.exists(savepath)#检查保存路径(文件夹)是否存在,若否则创建文件夹if (pathExist == False):os.mkdir(savepath)if re.match(r'.*jpg',i):#检查图片格式,未知图片格式则以png格式保存imageType = '.jpg'elif re.match(r'.*jpeg',i):imageType = '.jpeg'elif re.match(r'.*gif',i):imageType = '.gif'else:imageType = '.png'#open函数打开(创建)一个文件,其中模式'wb'表示以二进制格式打开一个文件只用于写入:#如果该文件已存在则打开文件,并从开头开始编辑,原有内容会被删除;如果该文件不存在,则创建新文件。save_image = open(savepath+'/'+str(count)+imageType,'wb')  save_image.write(img_data)save_image.close()count += 1

完整代码

import urllib.request
import requests
import re
import osdef getHTML(url,cookie):headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0','Cookie': cookie}try:html = requests.get(url,headers=headers,timeout=5)html.raise_for_status()html.encoding = 'utf-8'#r.apparent_encodingreturn html.textexcept:return 'something wrong'def getImageUrl(html):
#将html按空格分割并存入一个列表中,然后获取其中的图片urlhtml_splited = re.split(r'\s+',html) #对html文本按空格分割targetURL = [] #用于保存目标url的listfor i in html_splited:if (re.match(r'.*data-rt-src',i)): #筛选目标url的条件if (re.match(r'.*?png',i)) or (re.match(r'.*?jpg',i)) or (re.match(r'.*?jpeg',i)) or (re.match(r'.*?JPG',i)): #筛选目标url的条件                         if(re.match(r'.*http.*',i)): #筛选目标url的条件                if (re.match(r'.*\?',i)):url = re.search(r'.*src="(.*)\?',i).group(1) #获取准确图片url                else:url = re.search(r'.*src="(.*)"',i).group(1)targetURL.append(url)print(url)return targetURLdef crawlImage(urlList,savepath='folder'):
#根据图片的url,批量保存图片到本地count = 1for i in urlList:img_webpage = urllib.request.urlopen(i)img_data = img_webpage.read()pathExist = os.path.exists(savepath)#检查保存路径(文件夹)是否存在,若否则创建文件夹if (pathExist == False):os.mkdir(savepath)if re.match(r'.*jpg',i):#检查图片格式,未知图片格式则以png格式保存imageType = '.jpg'elif re.match(r'.*jpeg',i):imageType = '.jpeg'elif re.match(r'.*gif',i):imageType = '.gif'else:imageType = '.png'#open函数打开(创建)一个文件,其中模式'wb'表示以二进制格式打开一个文件只用于写入:#如果该文件已存在则打开文件,并从开头开始编辑,原有内容会被删除;如果该文件不存在,则创建新文件。save_image = open(savepath+'/'+str(count)+imageType,'wb')  save_image.write(img_data)save_image.close()count += 1        if __name__ == '__main__':    url ='http://www.mafengwo.cn/i/18845218.html'cookie='mfw_uuid=5e15a493-892d-30fd-8f7b-f9b427d723e0; _r=baidu; _rp=a%3A2%3A%7Bs%3A1%3A%22p%22%3Bs%3A18%3A%22www.baidu.com%2Flink%22%3Bs%3A1%3A%22t%22%3Bi%3A1578476691%3B%7D; __jsluid_h=59e2d5954da4576186658ea27c253918; __mfwa=1578476692581.63366.8.1584940053205.1584945013269; __mfwlv=1584940053; __mfwvn=5; __mfwlt=1584946062; uva=s%3A307%3A%22a%3A4%3A%7Bs%3A13%3A%22host_pre_time%22%3Bs%3A10%3A%222020-01-08%22%3Bs%3A2%3A%22lt%22%3Bi%3A1578476693%3Bs%3A10%3A%22last_refer%22%3Bs%3A180%3A%22https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3DzIIeEAiySnkbqfJPHb9C5AVbpHakB4DYW5hweW9_1G6COmUNxEebXW-syv4VC0rFGyXqsd14AbrOhpkq0m-rhQ77RyXSl3CxJFSI0WQeew7%26wd%3D%26eqid%3D8aa9855e0014e809000000065e15a48a%22%3Bs%3A5%3A%22rhost%22%3Bs%3A13%3A%22www.baidu.com%22%3B%7D%22%3B; __mfwurd=a%3A3%3A%7Bs%3A6%3A%22f_time%22%3Bi%3A1578476693%3Bs%3A9%3A%22f_rdomain%22%3Bs%3A13%3A%22www.baidu.com%22%3Bs%3A6%3A%22f_host%22%3Bs%3A3%3A%22www%22%3B%7D; __mfwuuid=5e15a493-892d-30fd-8f7b-f9b427d723e0; Hm_lvt_8288b2ed37e5bc9b4c9f7008798d2de0=1584854152,1584885764,1584928736,1584945013; UM_distinctid=16f848aebd79cd-088c79933954f78-4c302a7b-1fa400-16f848aebd84a5; CNZZDATA30065558=cnzz_eid%3D1650508070-1578473002-null%26ntime%3D1584945249; oad_n=a%3A3%3A%7Bs%3A3%3A%22oid%22%3Bi%3A1029%3Bs%3A2%3A%22dm%22%3Bs%3A15%3A%22www.mafengwo.cn%22%3Bs%3A2%3A%22ft%22%3Bs%3A19%3A%222020-03-22+13%3A15%3A49%22%3B%7D; __mfwc=direct; bottom_ad_status=0; PHPSESSID=d07def41hatb2or2i76ndgi0e7; Hm_lpvt_8288b2ed37e5bc9b4c9f7008798d2de0=1584946062; __jsl_clearance=1584949023.292|0|gKKMHG1iaq8wReTJEWUf6ebgBMk%3D'html = getHTML(url,cookie)targetURL = getImageUrl(html)crawlImage(targetURL,savepath='www.mafengwo.cn')

爬取的图片成功保存到本地:

后记

目前代码存在一个硬伤:所获取的网页html是不完整的,因此我也只抓到了这篇游记的前24张图片。
经过确认,确是蚂蜂窝页面异步加载的原因导致的,目前这个问题已经解决,请参看我下一篇博客。

python爬取蚂蜂窝帖子图片相关推荐

  1. Python 爬取蚂蜂窝旅游攻略 (+Scrapy框架+MySQL)

    前言:使用python+scrapy框架爬取蚂蜂窝旅游攻略 Git代码地址:https://github.com/qijingpei/mafengwo 获取代理IP地址的开源项目ProxyPool-m ...

  2. Python爬取蚂蜂窝教程

    最近因为项目需要,就去了解学习了Python爬虫的一些知识,并在此分享出学习过程中的难题和经验. 先看最终程序输出 {"website": "<a href=&qu ...

  3. python爬取图片-Python爬取网页中的图片(搜狗图片)详解

    前言 最近几天,研究了一下一直很好奇的爬虫算法.这里写一下最近几天的点点心得.下面进入正文: 你可能需要的工作环境: Python 3.6官网下载 本地下载 我们这里以sogou作为爬取的对象. 首先 ...

  4. Python 爬取陈都灵百度图片

    Python 爬取陈都灵百度图片 标签(空格分隔): 随笔 今天意外发现了自己以前写的一篇爬虫脚本,爬取的是我的女神陈都灵,尝试运行了一下发现居然还能用.故把脚本贴出来分享一下. import req ...

  5. 用Python爬取彼岸图网图片

     用Python爬取彼岸图网图片 *使用了  四个模块 import time import requests from lxml import etree import os 没有的话自行百度安装. ...

  6. python如何爬取网页视频_快就完事了!10分钟用python爬取网站视频和图片

    原标题:快就完事了!10分钟用python爬取网站视频和图片 话不多说,直接开讲!教你如何用Python爬虫爬取各大网站视频和图片. 638855753 网站分析: 我们点视频按钮,可以看到的链接是: ...

  7. Python爬取国家地理杂志的图片

    一.简介:Python爬取国家地理杂志的图片 二.代码展示 from bs4 import BeautifulSoup import requests import osos.mkdir('./img ...

  8. Python爬取 | 唯美女生图片

    这里只是代码展示,且复制后不能直接运行,需要配置一些设置才行,具体请查看下方链接介绍: Python爬取 | 唯美女生图片 from selenium import webdriver from fa ...

  9. 利用python爬取qq个性网图片

    利用python爬取qq个性网图片 网站头像布局大同小异,稍改代码即可爬取想要的头像. 不多bb,上代码. import requests from parsel import Selector im ...

最新文章

  1. Oracle的REGEXP_INSTR再mysql中实现
  2. Python--day28--set去重
  3. php使用curl下载指定大小的文件
  4. 52次课(mysql用户管理、常用sql语句、 mysql数据库备份恢复)
  5. iOS内存区域部分内容
  6. Java包装类与基本数据类型的自动 手动装箱与自动 手动拆箱
  7. E2: A Framework for NFV Applications, SOSP' 15
  8. ct上的img表示什么_明明胸部CT上已经写了肺癌,为什么还要做那么多花钱又痛苦的检查...
  9. Beginning WF 4.0翻译——第四章(传递参数)
  10. java单元测试笔记
  11. android 钢琴识别音阶对错_钢琴为什么会成为“乐器之王”
  12. 微信AI开放接口介绍
  13. JSONObject遍历
  14. JavaWeb各大组件生命周期
  15. OpenCV尽量不要打开CUDA参数编译,否则太慢了
  16. mysql 内连接、自然连接、外连接的区别
  17. 防止汽轮机严重超速的技术措施 22437
  18. 自学笔记----三极管
  19. 基于android的校园新闻app,移动端校园新闻APP的设计探析
  20. #4【BZOJ5109】[CodePlus 2017]大吉大利,晚上吃鸡!(未完成)

热门文章

  1. 基于Python的SQLite基础知识学习
  2. php手机建站,zzzphp免费开源建站系统含手机站
  3. VSS 2005 安装,配置简明手册 及VSS2005下载地址
  4. 006_STM32程序移植之_SYN6288语音模块
  5. 计算机怎么重装win7,如何重装电脑系统win7,最新电脑重装系统教程
  6. 终端设备的物联网控制方案
  7. gsensor direction调试
  8. 新氧2023年财务业绩预测:退市风险大幅降低,收入增长将放缓
  9. 51单片机定时器工作方式1、2原理详解
  10. kwebio/kweb-core:面向后端的轻量级 Kotlin Web 框架