1. 程式人生 > 其它 >使用Python 爬取 京東 ,淘寶。 商品詳情頁的資料。(避開了反爬蟲機制)

使用Python 爬取 京東 ,淘寶。 商品詳情頁的資料。(避開了反爬蟲機制)

以下是爬取京東商品詳情的Python3程式碼,以excel存放連結的方式批量爬取。excel如下

程式碼如下

from selenium import webdriver
from lxml import etree
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import datetime
import calendar
import logging
from logging import handlers
import requests
import os
import time
import pymssql
import openpyxl
import xlrd
import codecs



class EgongYePing: options = webdriver.FirefoxOptions() fp = webdriver.FirefoxProfile() fp.set_preference("browser.download.folderList",2) fp.set_preference("browser.download.manager.showWhenStarting",False) fp.set_preference("browser.helperApps.neverAsk.saveToDisk","application/zip,application/octet-stream
") global driver driver= webdriver.Firefox(firefox_profile=fp,options=options) def Init(self,url,code): print(url.strip()) driver.get(url.strip()) #driver.refresh() # 操作瀏覽器屬於非同步,在網路出現問題的時候。可能程式碼先執行。但是請求頁面沒有應答。所以硬等 time.sleep(
int(3)) html = etree.HTML(driver.page_source) if driver.title!=None: listImg=html.xpath('//*[contains(@class,"spec-list")]//ul//li//img') if len(listImg)==0: pass if len(listImg)>0: imgSrc='' for item in range(len(listImg)): imgSrc='https://img14.360buyimg.com/n0/'+listImg[item].attrib["data-url"] print('頭圖下載:'+imgSrc) try: Headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0'} r = requests.get(imgSrc, headers=Headers, stream=True) if r.status_code == 200: imgUrl='' if item==0: imgUrl+=code + "_主圖_" + str(item) + '.' + imgSrc.split('//')[1].split('/')[len(imgSrc.split('//')[1].split('/'))-1].split('.')[1] else: imgUrl+=code + "_附圖_" + str(item) + '.' + imgSrc.split('//')[1].split('/')[len(imgSrc.split('//')[1].split('/'))-1].split('.')[1] open(os.getcwd()+'/img/'+ imgUrl , 'wb').write(r.content) # 將內容寫入圖片 del r except Exception as e: print("圖片禁止訪問:"+imgSrc) listImg=html.xpath('//*[contains(@class,"ssd-module")]') if len(listImg)==0: listImg=html.xpath('//*[contains(@id,"J-detail-content")]//div//div//p//img') if len(listImg)==0: listImg=html.xpath('//*[contains(@id,"J-detail-content")]//img') if len(listImg)>0: for index in range(len(listImg)): detailsHTML=listImg[index].attrib if 'data-id' in detailsHTML: try: details= driver.find_element_by_class_name("animate-"+listImg[index].attrib['data-id']).value_of_css_property('background-image') details=details.replace('url(' , ' ') details=details.replace(')' , ' ') newDetails=details.replace('"', ' ') details=newDetails.strip() print("詳情圖下載:"+details) try: Headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0'} r = requests.get(details, headers=Headers, stream=True) if r.status_code == 200: imgUrl='' imgUrl+=code + "_詳情圖_" + str(index) + '.' + details.split('//')[1].split('/')[len(details.split('//')[1].split('/'))-1].split('.')[1] open(os.getcwd()+'/img/'+ imgUrl, 'wb').write(r.content) # 將內容寫入圖片 del r except Exception as e: print("圖片禁止訪問:"+details) except Exception as e: print('其他格式的圖片不收錄'); if 'src' in detailsHTML: try: details= listImg[index].attrib['src'] if 'http' in details: pass else: details='https:'+details print("詳情圖下載:"+details) try: Headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0'} r = requests.get(details, headers=Headers, stream=True) if r.status_code == 200: imgUrl='' imgUrl+=code + "_詳情圖_" + str(index) + '.' + details.split('//')[1].split('/')[len(details.split('//')[1].split('/'))-1].split('.')[1] open(os.getcwd()+'/img/'+ imgUrl, 'wb').write(r.content) # 將內容寫入圖片 del r except Exception as e: print("圖片禁止訪問:"+details) except Exception as e: print('其他格式的圖片不收錄'); print('結束執行') @staticmethod def readxlsx(inputText): filename=inputText inwb = openpyxl.load_workbook(filename) # 讀檔案 sheetnames = inwb.get_sheet_names() # 獲取讀檔案中所有的sheet,通過名字的方式 ws = inwb.get_sheet_by_name(sheetnames[0]) # 獲取第一個sheet內容 # 獲取sheet的最大行數和列數 rows = ws.max_row cols = ws.max_column for r in range(1,rows+1): for c in range(1,cols): if ws.cell(r,c).value!=None and r!=1 : if 'item.jd.com' in str(ws.cell(r,c+1).value) and str(ws.cell(r,c+1).value).find('i-item.jd.com')==-1: print('支援:'+str(ws.cell(r,c).value)+'|'+str(ws.cell(r,c+1).value)) EgongYePing().Init(str(ws.cell(r,c+1).value),str(ws.cell(r,c).value)) else: print('當前格式不支援:'+(str(ws.cell(r,c).value)+'|'+str(ws.cell(r,c+1).value))) pass pass if __name__ == "__main__": start = EgongYePing() start.readxlsx(r'C:\Users\newYear\Desktop\爬圖.xlsx')

基本上除了過期的商品無法訪問以外。對於京東的三種頁面結構都做了處理。能訪問到的商品頁面。還做了模擬瀏覽器請求訪問和下載。基本不會被反爬蟲遮蔽下載。

上面這一段是以火狐模擬器執行

上面這一段是模擬瀏覽器下載。如果不加上這一段。經常會下載幾十張圖片後,很長一段時間無法正常下載圖片。因為沒有請求頭被認為是爬蟲。

上面這段是京東的商品詳情頁面,經常會三種?(可能以後會更多的頁面結構)

所以做了三段解析。只要沒有抓到圖片就換一種解析方式。這楊就全了。

京東的圖片基本只存/1.jpg。然後域名是https://img14.360buyimg.com/n0/。所以目前要拼一下。

京東還有個很蛋疼的地方是圖片以data-id拼進div的背景元素裡。所以取出來的時候要繞一下。還好也解決了。

以下是爬取京東商品詳情的Python3程式碼,以excel存放連結的方式批量爬取。excel如下

因為這次是淘寶和京東一起爬取。所以在一個excel裡。程式碼裡區分淘寶和京東的連結。以下是程式碼

from selenium import webdriver
from lxml import etree
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import datetime
import calendar
import logging
from logging import handlers
import requests
import os
import time
import pymssql
import openpyxl
import xlrd
import codecs



class EgongYePing:

     options = webdriver.FirefoxOptions()
     fp = webdriver.FirefoxProfile()
     fp.set_preference("browser.download.folderList",2)  
     fp.set_preference("browser.download.manager.showWhenStarting",False)
     fp.set_preference("browser.helperApps.neverAsk.saveToDisk","application/zip,application/octet-stream")
     global driver 
     driver= webdriver.Firefox(firefox_profile=fp,options=options)
     def Init(self,url,code):
                       #driver = webdriver.Chrome('D:\python3\Scripts\chromedriver.exe')
                       #driver.get(url)
                       print(url.strip())
                       driver.get(url.strip())
                       #driver.refresh()
                       # 操作瀏覽器屬於非同步,在網路出現問題的時候。可能程式碼先執行。但是請求頁面沒有應答。所以硬等
                       time.sleep(int(3))
                       html = etree.HTML(driver.page_source) 
                       if driver.title!=None:
                         listImg=html.xpath('//*[contains(@id,"J_UlThumb")]//img')
                         if len(listImg)==0:
                              pass
                         if len(listImg)>0:
                                            imgSrc=''
                                            for item in range(len(listImg)):    
                                                 search=listImg[item].attrib
                                                 if 'data-src' in search:
                                                    imgSrc=listImg[item].attrib["data-src"].replace('.jpg_50x50','')
                                                 else:
                                                    imgSrc=listImg[item].attrib["src"]
                                                 if 'http' in imgSrc:
                                                     pass
                                                 else:
                                                     imgSrc='https:'+imgSrc
                                                 print('頭圖下載:'+imgSrc)
                                                 try:
                                                  Headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0'}
                                                  r = requests.get(imgSrc, headers=Headers, stream=True)
                                                  if r.status_code == 200:
                                                     imgUrl=''
                                                     if item==0:
                                                          imgUrl+=code + "_主圖_" + str(item)  + '.' + imgSrc.split('//')[1].split('/')[len(imgSrc.split('//')[1].split('/'))-1].split('.')[1]
                                                     else:
                                                          imgUrl+=code + "_附圖_" + str(item)  + '.' + imgSrc.split('//')[1].split('/')[len(imgSrc.split('//')[1].split('/'))-1].split('.')[1]
                                                     open(os.getcwd()+'/img/'+  imgUrl , 'wb').write(r.content) # 將內容寫入圖片
                                                  del r
                                                 except Exception as e:
                                                    print("圖片禁止訪問:"+imgSrc) 
                         listImg=html.xpath('//*[contains(@id,"J_DivItemDesc")]//img')
                         if len(listImg)>0:
                               for index in range(len(listImg)):  
                                    detailsHTML=listImg[index].attrib
                                    if 'data-ks-lazyload' in detailsHTML:
                                        details= listImg[index].attrib["data-ks-lazyload"]
                                        print("詳情圖下載:"+details)
                                    else:
                                        details= listImg[index].attrib["src"]
                                        print("詳情圖下載:"+details)
                                    try:
                                                  Headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0'}
                                                  r = requests.get(details, headers=Headers, stream=True)
                                                  if r.status_code == 200:
                                                     imgUrl=''
                                                     details=details.split('?')[0]
                                                     imgUrl+=code + "_詳情圖_" + str(index)  + '.' + details.split('//')[1].split('/')[len(details.split('//')[1].split('/'))-1].split('.')[1]
                                                     open(os.getcwd()+'/img/'+   imgUrl, 'wb').write(r.content) # 將內容寫入圖片
                                                  del r
                                    except Exception as e:
                                                    print("圖片禁止訪問:"+details)  
                       print('結束執行')

         

     @staticmethod
     def readxlsx(inputText):
        filename=inputText
        inwb = openpyxl.load_workbook(filename)  # 讀檔案
        sheetnames = inwb.get_sheet_names()  # 獲取讀檔案中所有的sheet,通過名字的方式
        ws = inwb.get_sheet_by_name(sheetnames[0])  # 獲取第一個sheet內容
        # 獲取sheet的最大行數和列數
        rows = ws.max_row
        cols = ws.max_column
        for r in range(1,rows+1):
            for c in range(1,cols):
                if ws.cell(r,c).value!=None and r!=1 :
                 if 'item.taobao.com' in str(ws.cell(r,c+1).value):
                     print('支援:'+str(ws.cell(r,c).value)+'|'+str(ws.cell(r,c+1).value))
                     EgongYePing().Init(str(ws.cell(r,c+1).value),str(ws.cell(r,c).value))
                 else:
                     print('當前格式不支援:'+(str(ws.cell(r,c).value)+'|'+str(ws.cell(r,c+1).value)))
                     pass
        pass

if __name__ == "__main__":
                 start = EgongYePing()
                 start.readxlsx(r'C:\Users\newYear\Desktop\爬圖.xlsx')

淘寶有兩個問題,一個是需要繫結賬號登入訪問。這裡是程式碼斷點。然後手動走過授權。

第二個是被休息和懶惰載入。被休息。其實沒影響的。一個頁面結構已經加載出來了。然後也不會影響訪問其他的頁面。

至於懶惰載入嘛。對我們也沒啥影響。如果不是直接寫在src裡那就在判斷一次取data-ks-lazyload就出來了。

最後就是爬取的片段截圖

建議還是直接將爬取的資料存伺服器,資料庫,或者圖片伺服器。因為程式挺靠譜的。一萬條資料。爬了26個G的檔案。最後上傳的時候差點累死了

是真的大。最後還要拆包。十幾個2g壓縮包一個一個上傳。才成功。