1. 程式人生 > >比價網站的基礎-爬取淘寶的商品資訊

比價網站的基礎-爬取淘寶的商品資訊

淘寶網站,頁面上有很多動態載入的AJAX請求,並且很多引數做過加密處理,如果直接分析網頁,會非常繁瑣,難度極大。本文利用selenium驅動chrome瀏覽器完成關鍵字輸入、搜尋、點選等功能,完成頁面的資訊的獲取,並利用pyquery庫進行解析,獲取商品資訊並將資訊存入mongodb。
selenium庫的安裝已經具體使用方法詳見部落格http://blog.csdn.net/qq_29186489/article/details/78661008,
關於mongodb的安裝與配置,詳見部落格http://blog.csdn.net/qq_29186489/article/details/78546727,本文不再贅述。

抓取思路分析##

1:利用selenium驅動chrome瀏覽器進入淘寶網站,手工輸入賬號密碼後,獲取cookies,並存儲到本地;在爬取程式執行時,從本地載入cookies,維持登入;
2:利用selenium驅動chrome瀏覽器進入淘寶網站,輸入關鍵詞“美食”,並點選搜尋按鈕,得到商品查詢後的列表;
這裡寫圖片描述3:載入搜尋結果頁面完成後,分析頁碼,得到商品的頁碼數,模擬翻頁,每次翻頁,停止10-30秒的休眠時間,得到後續頁面的商品列表;
4:利用pyquery解析頁面,分析獲取商品資訊;
5:將獲取到的商品資訊儲存到mongodb中,供後續分析使用。

編碼實現

一:獲取cookies,並存儲到本地

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
import time
import json
browser=webdriver.Chrome()
browser.get("https://www.taobao.com")
input=browser.find_element_by_css_selector("#q")
input.send_keys("ipad")
button=browser.find_element_by_class_name("btn-search")
button.click()
#留下時間,掃描二維碼登入
time.sleep(20)
#登入後,儲存cookies到本地
dictCookies=browser.get_cookies()
jsonCookies=json.dumps(dictCookies)
with open("cookies.txt","w") as f:
    f.write(jsonCookies)

browser.close()

二:載入cookies,執行爬蟲程式,獲取商品資訊
1:引入相關類庫

from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import re
from pyquery import PyQuery as pq
import pymongo
import random
import time

2:定義MONGO資料庫的連結引數

MONGO_URL="LOCALHOST"
MONGO_DB="taobao"
MONGO_TABLE="product"
client=pymongo.MongoClient(MONGO_URL)
db=client[MONGO_DB]

3:載入cookies資訊,並維持登入

#載入cookie,維持登入
def load_cookie(browser,file):
    browser.get("https://www.taobao.com")
    browser.maximize_window()
    browser.delete_all_cookies()
    # 讀取登入時儲存到本地的cookie
    with open(file, 'r', encoding='utf-8') as f:
        listCookies = json.loads(f.read())

    for cookie in listCookies:
        browser.add_cookie(cookie)
    browser.refresh()
    return browser

3:搜尋商品資訊

#搜尋商品資訊
def search_html(browser):
    try:
        browser=load_cookie(browser,"cookies.txt")
        #等待搜尋框載入並獲取該元素
        input_element=WebDriverWait(browser,10).until(
            EC.presence_of_element_located((By.CSS_SELECTOR,"#q"))
        )
        #等待搜尋按鈕並獲取該元素
        search_button=WebDriverWait(browser,10).until(
            EC.presence_of_element_located((By.CSS_SELECTOR,"#J_TSearchForm > div.search-button > button"))
        )
        #輸入關鍵字 美食
        input_element.send_keys("美食")
        #點選搜尋按鈕
        search_button.click()
        page_total_num=WebDriverWait(browser,10).until(
            EC.presence_of_element_located((By.CSS_SELECTOR,"#mainsrp-pager > div > div > div > div.total"))
        )
        num=re.findall('共.*?(\d+).*?頁',page_total_num.text,re.S)[0]
        #time.sleep(1000)
        return num

    except TimeoutException:
        return None

4:實現翻頁功能

#實現翻頁功能,由於淘寶的反抓取設定,翻頁太快會被遮蔽,翻頁時間設定為15秒每次
def next_page(page_num):
    try:
        #等待頁碼輸入框載入成功,並獲取該物件
        input_pagenum=WebDriverWait(browser,10).until(
            EC.presence_of_element_located((By.CSS_SELECTOR,"#mainsrp-pager > div > div > div > div.form > input"))
        )
        #等待翻頁確定按鈕載入成功,並獲取該物件
        button_confirm=WebDriverWait(browser,10).until(
            EC.presence_of_element_located((By.CSS_SELECTOR,"#mainsrp-pager > div > div > div > div.form > span.btn.J_Submit"))
        )
        #清空頁碼輸入框
        input_pagenum.clear()
        #輸入跳轉的頁碼
        input_pagenum.send_keys(page_num)
        #點選頁碼跳轉確認按鈕
        button_confirm.click()
        #判斷跳轉後頁面的頁面是否和輸入的一致
        WebDriverWait(browser,10).until(
            EC.text_to_be_present_in_element((By.CSS_SELECTOR,"#mainsrp-pager > div > div > div > ul > li.item.active > span"),str(page_num))
        )
        #每隔10-30秒隨機事件翻頁
        time.sleep(random.randint(10, 30))
    except TimeoutException:
        next_page(page_num)

5:解析網頁程式碼,獲取商品資訊

#解析網頁程式碼,獲取商品資訊
def get_products():
    #判斷商品資訊是否載入完成
    WebDriverWait(browser,10).until(EC.presence_of_element_located((By.CSS_SELECTOR,"#mainsrp-itemlist .items .item")))
    #獲取載入完成的網頁程式碼
    html=browser.page_source
    #利用pyquery解析網頁程式碼
    doc=pq(html)
    #獲取所有的商品資訊的列表
    items=doc("#mainsrp-itemlist .items .item").items()
    #遍歷獲取每個商品的資訊
    for item in items:
        product={
            'image':item.find(".pic .img").attr("src"),
            'price':item.find(".price").text(),
            'deal':item.find(".deal-cnt").text()[:-3],
            'title':item.find(".title").text(),
            'shop':item.find(".shop").text(),
            'location':item.find(".location").text()
        }
        save_to_mongo(product)

6:將結果儲存到mongodb中

def save_to_mongo(result):
    try:
        if db[MONGO_TABLE].insert(result):
            print("儲存到mongodb成功",result)
    except Exception:
        print("儲存到mongodb失敗",result)

7:程式入口

try:
    browser = webdriver.Chrome()
    total_num=int(search_html(browser))
    for page_num in range(2,total_num+1):
        get_products(browser)
        next_page(page_num)
except:
    print("執行出錯,請重試!")
finally:
    browser.close()

程式執行結果

控制檯截圖
這裡寫圖片描述
資料庫截圖
這裡寫圖片描述

程式完整程式碼下載地址