首頁  >  文章  >  後端開發  >  Python3實戰爬蟲之爬取京東圖書的圖文詳解

Python3實戰爬蟲之爬取京東圖書的圖文詳解

黄舟
黄舟原創
2017-10-09 10:22:372805瀏覽

最近在學習python3,以下這篇文章主要給大家介紹了關於Python3實戰爬蟲之爬取京東圖書圖片的相關資料,文中透過範例程式碼介紹的非常詳細,對大家的學習或工作具有一定的參考學習價值,需要的朋友們下面來一起看看吧。

前言

最近工作中遇到一個需求,需要將京東上圖書的圖片下載下來,假如我們想把京東商城圖書類的圖片類商品圖片全部下載到本地,透過手工複製貼上將是一項非常龐大的工程,此時,可以用Python網絡爬蟲實現,這類爬蟲稱為圖片爬蟲,接下來,我們將實現該爬蟲。

實作分析

首先,開啟要爬取的第一個網頁,這個網頁將會作為要爬取的起始頁面。我們打開京東,選擇圖書分類,由於圖書所有種類的圖書有很多,我們選擇爬取所有程式語言的圖書圖片吧,網址為:https://list.jd.com/list.html?cat=1713, 3287,3797&page=1&sort=sort_rank_asc&trans=1&JL=6_0_0#J_main

#如圖:

##進去後,我們會發現總共有251頁。

那我們怎麼能自動爬取第一頁以外的其他頁面呢?

可以點選“下一頁”,觀察網址的變化。在點擊了下一頁之後,發現網址變成了https://list.jd.com/list.html?cat=1713,3287,3797&page=2&sort=sort_rank_asc&trans=1&JL=6_0_0#J_main。

我們可以發現,在這裡要取得第幾頁是透過URL網址識別的,也就是透過GET方式請求的。在這個GET請求中,有多個字段,其中有一個字段為page,對應值為2,由此,我們可以得到該網址中的關鍵資訊為:https://list.jd.com/list.html ?cat=1713,3287,3797&page=2。接下來,我們根據推測,將page=2改成page=6,發現我們能夠成功進入第6頁。

由此,我們可以想到自動取得多個頁面的方法:可以使用for循環實現,每次循環後,對應的網址中page欄位加1,即自動切換到下一頁。

在每頁中,我們都要提取對應的圖片,可以使用正規表示式匹配原始碼中圖片的連結部分,然後透過urllib.request.urlretrieve()將對應連結的圖片儲存到本地。

但是這裡有一個問題,該網頁中的圖片不僅包括列表中的商品圖片,還包括旁邊的一些無關圖片,所以我們可以先進行一次資訊過濾,第一次資訊過濾將中間的商品清單部分資料留下,將其他部分的資料過濾掉。可以按一下右鍵,然後查看網頁的原始碼,如圖:

可以透過商品清單中的第一個商品名為「JAVA從入門到精通」快速定位到原始碼中的對應位置,然後觀察其商品列表部分的特殊標識,可以看到,其上方有處“

<p id="plist".+? <p class="page clearfix">

進行了第一次訊息過濾後,留下來的圖片連結就是我們想爬取的圖片了,下一步需要在第一次過濾的基礎上,再將圖片連結資訊過濾出來。觀察到其中兩張圖片的對應原始碼:

圖片1:


#

 <img width="200" height="200" data-img="1" src="//img13.360buyimg.com/n7/jfs/t6130/167/771989293/235186/608d0264/592bf167Naf49f7f6.jpg">

圖片2:


<img width="200" height="200" data-img="1" src="//img10.360buyimg.com/n7/g14/M03/0E/0D/rBEhV1Im1n8IAAAAAAcHltD_3_8AAC0FgC-1WoABweu831.jpg">

比較兩張圖片代碼,發現其基本格式是一樣的,只是圖片的連結網址不一樣,所以此時,我們根據該規律構造出提取圖片連結的正規表示式:


<img width="200" height="200" data-img="1" src="//(.+?\.jpg)">

刚开始到这里,我以为就结束了,后来在爬取的过程中我发现每一页都少爬取了很多图片,再次查看源码发现,每页后面的几十张图片又是另一种格式:


<img width="200" height="200" data-img="1" src-img="//img10.360buyimg.com/n7/jfs/t3226/230/618950227/110172/7749a8bc/57bb23ebNfe011bfe.jpg">

所以,完整的正则表达式应该是这两种格式的或:


<img width="200" height="200" data-img="1" src="//(.+?\.jpg)">|

到这里,我们根据该正则表达式,就可以提取出一个页面中所有想要爬取的图片链接。

所以,根据上面的分析,我们可以得到该爬虫的编写思路与过程,具体如下:

  • 建立一个爬取图片的自定义函数,该函数负责爬取一个页面下的我们想爬取的图片,爬取过程为:首先通过urllib.request.utlopen(url).read()读取对应网页的全部源代码,然后根据上面的第一个正则表达式进行第一次信息过滤,过滤完成之后,在第一次过滤结果的基础上,根据上面的第二个正则表达式进行第二次信息过滤,提取出该网页上所有的目标图片的链接,并将这些链接地址存储的一个列表中,随后遍历该列表,分别将对应链接通过urllib.request.urlretrieve(imageurl,filename=imagename)存储到本地,为了避免程序中途异常崩溃,我们可以建立异常处理。

  • 通过for循环将该分类下的所有网页都爬取一遍,链接可以构造为url='https://list.jd.com/list.html?cat=1713,3287,3797&page=' + str(i)

完整的代码如下:


#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import re
import urllib.request
import urllib.error
import urllib.parse


sum = 0
def craw(url,page):
 html1=urllib.request.urlopen(url).read()
 html1=str(html1)
 pat1=r'<p id="plist".+? <p class="page clearfix">'
 result1=re.compile(pat1).findall(html1)
 result1=result1[0]
 pat2=r'<img width="200" height="200" data-img="1" src="//(.+?\.jpg)">|'
 imagelist=re.compile(pat2).findall(result1)
 x=1
 global sum
 for imageurl in imagelist:
  imagename='./books/'+str(page)+':'+str(x)+'.jpg'
  if imageurl[0]!='':
   imageurl='http://'+imageurl[0]
  else:
   imageurl='http://'+imageurl[1]
  print('开始爬取第%d页第%d张图片'%(page,x))

  try:
   urllib.request.urlretrieve(imageurl,filename=imagename)
  except urllib.error.URLError as e:
   if hasattr(e,'code') or hasattr(e,'reason'):
    x+=1

  print('成功保存第%d页第%d张图片'%(page,x))
  x+=1
  sum+=1

for i in range(1,251):
 url='https://list.jd.com/list.html?cat=1713,3287,3797&page='+str(i)
 craw(url,i)
print('爬取图片结束,成功保存%d张图'%sum)

运行结果如下:

总结

以上是Python3實戰爬蟲之爬取京東圖書的圖文詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn