天天看點

python 擷取li的内容_python爬蟲xpath篇-以爬取京東商品資訊為例附思路和詳細代碼注釋...

python 擷取li的内容_python爬蟲xpath篇-以爬取京東商品資訊為例附思路和詳細代碼注釋...

這兩天在學習python爬蟲,有了一些對爬蟲的了解和心得。學習的時候在網上查過許多資料,但是由于自己是小白,是以學的時候總是覺得網上的例子不夠實在,對我來說有點難懂。然後這段時間學了爬蟲之後,也成功實作了幾個執行個體,有了一些了解、思路和方法。為了能夠幫助更多的初學者快速入門簡單的爬蟲,寫下這篇文章希望可以對大家有幫助。

這篇文章我主要是通過分享一個執行個體,來幫助大家了解爬蟲的概念、html資訊擷取方法、如何用xpath定位和擷取html内容,以及儲存爬到的資訊到excel表格。

本文的任務:擷取京東surface pro 7第一頁顯示的所有商品的名稱、連結、價格和店鋪名稱(例子用到的網址點這裡),并儲存到excel表格中。

本文分成以下幾個部分:

  1. 爬蟲是個啥?
  2. 我要在上面那個連結裡完成擷取商品資訊這個任務,我要怎麼做(分幾個步驟)?要用到什麼工具(一些python包)?
  1. 首先,我想先說下我對爬蟲的了解。我們可以将爬蟲看成一個複制粘貼工具,它是在我們浏覽一個網頁時,代替我們人工去對網頁上展示的部分資訊進行複制和粘貼到本地的一個工具。(比如我浏覽京東的時候,特别想把全部的商品名稱和價格複制下來,然後整理到一個excel上,但是一般一個頁面有30個商品,手動複制粘貼太慢了,那麼爬蟲就可以幫你把這些特定的資訊自動複制下來,你所要做的就是設定複制的規則即可)
  2. 要完成一個爬蟲的任務(本文任務為例),可以分成以下幾個步驟:
  • 爬取整個網頁資訊:
    • 你需要獲得網址的html資訊(浏覽器按F12可以檢視),因為你看到的整個頁面的所有内容都儲存在html資訊裡(自然也包括我們要的所有商品資訊):
python 擷取li的内容_python爬蟲xpath篇-以爬取京東商品資訊為例附思路和詳細代碼注釋...

f12檢視目前頁面html資訊,點選右側欄的左上角那個滑鼠後,還可以在左邊點選網頁裡的任意對象,它會自動定位你選擇的對象在右邊代碼塊的位置

from 
           
  • 從爬取到的整個網頁資訊中篩選出你想要的資訊(用xpath路徑擷取):

擷取資訊有許多方法,有用BeautiSoup定位資訊的、有用re正規表達式的,還可以用xpath定位路徑的。試了一圈下來,我個人覺得還是xpath路徑友善,也比較适合我(正規表達式太複雜了我完全記不住)。主要是xpath路徑浏覽器就可以直接獲得,比如下圖找到價格後,隻要右鍵就可以檢視價格所在的完整xpath路徑了。

python 擷取li的内容_python爬蟲xpath篇-以爬取京東商品資訊為例附思路和詳細代碼注釋...

檢視某一個價格的完整xpath路徑,複制到的資訊為"/html/body/div[7]/div/div[2]/div[1]/div/div[2]/ul/li[1]/div/div[2]/strong/i"

# 由于這個例子是隻爬取單個頁面,是以直接看下頁面有多少個商品,進行循環查找就行
# 如果是要爬取多個頁面,則可以再用一個循環來修改url頁面參數
# 比如豆瓣電影top250,第一頁是https://movie.douban.com/top250?start=0&filter=
# 第二頁是https://movie.douban.com/top250?start=25&filter=
# 隻要設出參數X,X為25*N,N=0,1,...,對X循環即可
# 對應的url=https://movie.douban.com/top250?start=X&filter=
# 表示從第X個電影開始給出25個電影資訊,實際上就是N頁
# 京東的翻頁也同理
# 如果想要對仍以一個關鍵詞爬取資訊,則要先把關鍵詞轉換為二進制編碼,然後替換url中的keyword部分即可

# 先看看我們要找什麼内容,把他們對應的xpath路徑先找一個出來:
# 浏覽器檢查html(F12):定位到對應内容的html源碼,将完整xpath路徑複制下來
# 商品名稱=/html/body/div[7]/div/div[2]/div[1]/div/div[2]/ul/li[7]/div/div[3]/a/em/text()
# 商品連結=/html/body/div[7]/div/div[2]/div[1]/div/div[2]/ul/li[7]/div/div[3]/a/@href
# 商品價格=/html/body/div[7]/div/div[2]/div[1]/div/div[2]/ul/li[7]/div/div[2]/strong/i/text()
# 店鋪名稱=/html/body/div[7]/div/div[2]/div[1]/div/div[2]/ul/li[4]/div/div[5]/span/a/
# 以商品名稱的xpath路徑為例,結合html源碼,可以看到,如果要找其它的商品名稱,隻要修改li[4]裡面的數字即可
# 後面就好操作了,用個循環表示所有商品資訊,改一下路徑的字元串就可以了
# 大緻為:爬每一個商品資訊,存到list裡,把list的資訊寫到excel中儲存,完成。
'''
temp = "/html/body/div[7]/div/div[2]/div[1]/div/div[2]/ul/li[7]/div/div[3]/a/em/text()"
temp1 = selector.xpath(temp)
print(temp1)
# /html/body/div[7]/div/div[2]/div[1]/div/div[2]/ul/li[7]/div/div[2]/strong/i
# /html/body/div[7]/div/div[2]/div[1]/div/div[2]/ul/li[1]/div/div[3]/a/em
# /html/body/div[7]/div/div[2]/div[1]/div/div[2]/ul/li[2]/div/div[3]/a/em
# /html/body/div[7]/div/div[2]/div[1]/div/div[2]/ul/li[7]/div/div[3]/a/em/text()
/html/body/div[7]/div/div[2]/div[1]/div/div[2]/ul/li[1]/div/div[2]/strong/i
/html/body/div[7]/div/div[2]/div[1]/div/div[2]/ul/li[30]/div/div[2]/strong/i
'''
datalist = []# 建立一個總表
# 一個頁面有30個商品資訊
for i in range(0, 30):
    data = []#建立一個儲存每一個商品資訊的清單
    t = str(i+1) # 修改xpath路徑li[i]的數字
    firstlink = "/html/body/div[6]/div[3]/div[2]/div[1]/div/div[2]/ul/li["

    # 商品名稱
    name1 = "/html/body/div[7]/div/div[2]/div[1]/div/div[2]/ul/li["
    name2 = "]/div/div[3]/a/em/text()" #加了/text()來擷取文本内容
    name3 = name1 + t + name2
    name = selector.xpath(name3)
    data.append(name)

    # 商品連結
    link1 = "/html/body/div[7]/div/div[2]/div[1]/div/div[2]/ul/li["
    link2 = "]/div/div[3]/a/@href"
    link3 = link1 + t + link2
    link = selector.xpath(link3)
    data.append(link)

    # 商品價格
    price1 = "/html/body/div[7]/div/div[2]/div[1]/div/div[2]/ul/li["
    price2 = "]/div/div[2]/strong/i/text()"
    price3 = price1 + t + price2
    price = selector.xpath(price3)
    data.append(price)

    #店鋪名稱
    shopname1 = "/html/body/div[7]/div/div[2]/div[1]/div/div[2]/ul/li["
    shopname2 = "]/div/div[5]/span/a/text()"
    shopname3 = shopname1 + t + shopname2
    shopname = selector.xpath(shopname3)
    data.append(shopname)
    datalist.append(data)
           
  • 将篩選出來的資訊儲存到excel工作表中
# 資訊爬完了,是時候存到excel裡了
# 此時的清單是有30行,4列
work = xlwt.Workbook(encoding="utf-8")
sheet = work.add_sheet("surface pro 7京東資訊表", cell_overwrite_ok=True)
col = ("商品名稱","商品連結","商品價格","店鋪名稱") # 準備excel表頭
for i in range(0,4):
    sheet.write(0, i, col[i])# 寫入表頭

print(len(datalist))

for i in range(0,30):
    print("第%d條"%(i+1))
    data = datalist[i] # 寫第i個商品資訊
    for j in range(0,4):
        if len(data[j]) != 0:
            sheet.write(i + 1, j, data[j])
        else:
            sheet.write(i + 1, j, "翻車") # 因為我發現有少數幾個店鋪傳回的資訊是空的

work.save("surface pro 7京東資訊表.xls")
print("爬取完畢!請到檔案目錄下檢視表格")
           
  • 最後貼上完整代碼
from scrapy import Selector
from lxml import etree
import urllib.request
import urllib.parse
import xlwt

url = r'https://list.jd.com/list.html?cat=670%2C671%2C2694&ev=exbrand_%E5%BE%AE%E8%BD%AF%EF%BC%88Microsoft%EF%BC%89%5E1107_90246%5E244_116227%5E3753_76033%5E&cid3=2694'

head = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36 Edg/84.0.522.40"}

# 準備好head辨別後,網頁發送請求,獲得html資料
req = urllib.request.Request(url, headers=head)
response = urllib.request.urlopen(req)
# 将獲得的資料解碼成utf-8格式
html = response.read().decode("utf-8")
# 解析html資訊,生成資訊樹
selector = etree.HTML(html)

# 由于這個例子是隻爬取單個頁面,是以直接看下頁面有多少個商品,進行循環查找就行
# 如果是要爬取多個頁面,則可以再用一個循環來修改url頁面參數
# 比如豆瓣電影top250,第一頁是https://movie.douban.com/top250?start=0&filter=
# 第二頁是https://movie.douban.com/top250?start=25&filter=
# 隻要設出參數X,X為25*N,N=0,1,...,對X循環即可
# 對應的url=https://movie.douban.com/top250?start=X&filter=
# 表示從第X個電影開始給出25個電影資訊,實際上就是N頁
# 京東的翻頁也同理
# 如果想要對仍以一個關鍵詞爬取資訊,則要先把關鍵詞轉換為二進制編碼,然後替換url中的keyword部分即可

# 先看看我們要找什麼内容,把他們對應的xpath路徑先找一個出來:
# 浏覽器檢查html(F12):我們随便定位到幾個對應内容的html源碼,将完整xpath路徑複制下來
# 商品名稱=/html/body/div[7]/div/div[2]/div[1]/div/div[2]/ul/li[7]/div/div[3]/a/em/text()
# 商品連結=/html/body/div[7]/div/div[2]/div[1]/div/div[2]/ul/li[7]/div/div[3]/a/@href
# 商品價格=/html/body/div[7]/div/div[2]/div[1]/div/div[2]/ul/li[7]/div/div[2]/strong/i/text()
# 店鋪名稱=/html/body/div[7]/div/div[2]/div[1]/div/div[2]/ul/li[4]/div/div[5]/span/a/
# 以商品名稱的xpath路徑為例,結合html源碼,可以看到,如果要找其它的商品名稱,隻要修改li[4]裡面的數字即可
# 後面就好操作了,用個循環表示所有商品資訊,改一下路徑的字元串就可以了
# 大緻為:爬每一個商品資訊,存到list裡,把list的資訊寫到excel中儲存,完成。
'''
temp = "/html/body/div[7]/div/div[2]/div[1]/div/div[2]/ul/li[7]/div/div[3]/a/em/text()"
temp1 = selector.xpath(temp)
print(temp1)
# /html/body/div[7]/div/div[2]/div[1]/div/div[2]/ul/li[7]/div/div[2]/strong/i
# /html/body/div[7]/div/div[2]/div[1]/div/div[2]/ul/li[1]/div/div[3]/a/em
# /html/body/div[7]/div/div[2]/div[1]/div/div[2]/ul/li[2]/div/div[3]/a/em
# /html/body/div[7]/div/div[2]/div[1]/div/div[2]/ul/li[7]/div/div[3]/a/em/text()
/html/body/div[7]/div/div[2]/div[1]/div/div[2]/ul/li[1]/div/div[2]/strong/i
/html/body/div[7]/div/div[2]/div[1]/div/div[2]/ul/li[30]/div/div[2]/strong/i
'''
datalist = []# 建立一個總表
# 一個頁面有30個商品資訊
for i in range(0, 30):
    data = []#建立一個儲存每一個商品資訊的清單
    t = str(i+1) # 修改xpath路徑li[i]的數字
    firstlink = "/html/body/div[6]/div[3]/div[2]/div[1]/div/div[2]/ul/li["

    # 商品名稱
    name1 = "/html/body/div[7]/div/div[2]/div[1]/div/div[2]/ul/li["
    name2 = "]/div/div[3]/a/em/text()" #加了/text()來擷取文本内容
    name3 = name1 + t + name2
    name = selector.xpath(name3)
    data.append(name)

    # 商品連結
    link1 = "/html/body/div[7]/div/div[2]/div[1]/div/div[2]/ul/li["
    link2 = "]/div/div[3]/a/@href"
    link3 = link1 + t + link2
    link = selector.xpath(link3)
    data.append(link)

    # 商品價格
    price1 = "/html/body/div[7]/div/div[2]/div[1]/div/div[2]/ul/li["
    price2 = "]/div/div[2]/strong/i/text()"
    price3 = price1 + t + price2
    price = selector.xpath(price3)
    data.append(price)

    #店鋪名稱
    shopname1 = "/html/body/div[7]/div/div[2]/div[1]/div/div[2]/ul/li["
    shopname2 = "]/div/div[5]/span/a/text()"
    shopname3 = shopname1 + t + shopname2
    shopname = selector.xpath(shopname3)
    data.append(shopname)
    datalist.append(data)

# 資訊爬完了,是時候存到excel裡了 # 此時的清單是有30行,4列
work = xlwt.Workbook(encoding="utf-8") 
sheet = work.add_sheet("surface pro 7京東資訊表", cell_overwrite_ok=True) 
col = ("商品名稱","商品連結","商品價格","店鋪名稱") 
# 準備excel表頭 
for i in range(0,4):     
    sheet.write(0, i, col[i])# 寫入表頭  
    print(len(datalist))  
for i in range(0,30):     
    print("第%d條"%(i+1))     
    data = datalist[i] # 寫第i個商品資訊     
    for j in range(0,4):         
        if len(data[j]) != 0:             
        sheet.write(i + 1, j, data[j])         
        else:             
        sheet.write(i + 1, j, "翻車") # 因為我發現有少數幾個店鋪傳回的資訊是空的  
work.save("surface pro 7京東資訊表.xls") 
print("爬取完畢!請到檔案目錄下檢視表格")
           
  • 效果如下:
python 擷取li的内容_python爬蟲xpath篇-以爬取京東商品資訊為例附思路和詳細代碼注釋...

店鋪名稱有兩個地方傳回空資訊,是以代碼用"翻車"代替了.單獨列印第一個xpath路徑是"/html/body/div[7]/div/div[2]/div[1]/div/div[2]/ul/li[7]/div/div[5]/span/a",傳回的是[],直到"/html/body/div[7]/div/div[2]/div[1]/div/div[2]/ul/li[7]/div/div[5]"才傳回[<

  • 總結:個人覺得一個完整的爬蟲代碼,主要分為html資訊擷取、html資訊篩選和資訊儲存三個步驟。而最重要也是最容易出錯的地方就是制定資訊篩選規則部分了(如代碼中找xpath路徑的部分,從上圖看出有兩個店鋪傳回的是空資訊,有可能是這兩個店鋪的路徑規則和其它的不同的問題)。
  • 而html資訊擷取環節,一般的網頁帶上headers就可以防止伺服器反爬了,更深一點的反爬以及動态資訊部分,我的了解還不夠深刻,是以暫時不讨論了。不過我記得動态資訊(如下拉加載更多等)可以f12後查找js資訊也許可以獲得真實的網址以及後續加載的文本内容(比如b站就是這樣(b站首頁除外),比如單機遊戲區的按視訊熱度排序得到的結果資訊并沒有儲存在html裡面,而是儲存在js是以獲得的html資訊不包含這些内容。當然這一段話是個人了解,也不知道準不準确,希望有看到的大佬能夠在評論區指點指點)
python 擷取li的内容_python爬蟲xpath篇-以爬取京東商品資訊為例附思路和詳細代碼注釋...

視訊儲存在js部分

繼續閱讀