使用selenium和pyquery來爬取淘寶ipad商品資訊
阿新 • • 發佈:2018-12-15
使用selenium爬取淘寶ipad商品資訊
- 爬取過程中的重點是實現翻頁、提取商品資訊、儲存至資料庫
訪問淘寶
爬取過程中可以通過掃描二維碼的方式來登陸淘寶,要注意的是訪問不能過於頻繁,否則ip會被限制訪問。 防止ip被限制訪問可以通過使用代理,或者降低訪問的頻率
1.獲取商品的總頁數
- 檢查其html原始碼
- 可通過CSS選擇器來選取總頁數,進而獲取其總頁數 程式碼如下:
def search(url): # 獲取商品的總頁數 try: browser.get(url) # 訪問url browser.maximize_window() # 最大化瀏覽器 sum = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '#mainsrp-pager > div > div > div > div.total'))) # 等待總頁數的加載出現 return int(sum.text[1:-2]) # 擷取價格的數字部分,第二個元素至倒數第二個元素 # 返回總頁數 except TimeoutException: search(url)
2.實現翻頁操作
- 這裡通過頁數輸入框和確定按鈕來實現翻頁操作,而不是用下一頁按鈕。因為如果使用下一頁按鈕的話,需要記錄頁數,而且如果中間出錯的話,無法判別正確頁數是哪一個,及後續操作無法進行
- 同樣的,通過CSS選擇器來選取輸入框和確定按鈕
input = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,'#mainsrp-pager > div > div > div > div.form > input'))) # 等待輸入框加載出現,並選取 submit = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,'#mainsrp-pager > div > div > div > div.form > span.btn.J_Submit'))) # 等待確定按鈕加載出現(element_to_be_clickable可點選元素,來確定是按鈕元素),並選取
- 翻頁時,首先清空輸入框中的內容,再輸入目標頁,單擊確定按鈕,實現翻頁
input.clear()
# 清除輸入框內容
input.send_keys(page)
# 將要跳轉的頁數輸入到輸入框中
submit.click()
# 點選確定按鈕
- 翻頁之後還需要判斷該頁是否與我們的目標頁是同一頁 選取高亮的頁碼數,與目標頁數比較
wait.until(EC.text_to_be_present_in_element((By.CSS_SELECTOR, '#mainsrp-pager > div > div > div > ul > li.item.active > span'), str(page))) # 選擇高亮的頁碼數,判斷它是否等於我們所跳轉的頁數(str(page))
接著,在分析原始碼的時候我們發現,所有的資訊都在class值為item的標籤之中,所以首先要等在這些原始碼載入成功,進而在其內通過pyquery提取資訊 這裡有五個item,內含五個商品的資訊(item與之後的內容間隔一個空格,所以選擇的時候class屬性直接指定為item) 內部資訊如下: 提取資訊的程式碼如下:
def get_products():
# 用pyquery解析網頁
html = browser.page_source # 獲取原始碼
doc = pq(html) # 生成pyquery物件
items = doc('#mainsrp-itemlist .items .item').items() # items()得到一個可遍歷的生成器
for item in items:
product = {
'image': item('.pic').find('img').attr('data-src'), # 提取image
'price': item('.price').text(), # 提取價格
'deal': item('.deal-cnt').text()[:-3], # 擷取第一個字元至倒數第三個字元
'location': item('.location').text() # 提取店鋪位置
}
print(product) # 列印資訊
save_to_mongo(product) # 將提取到的資訊儲存到MongoDB資料庫中
3.將資料儲存到MongoDB資料庫中
使用pymongo庫與MongoDB進行互動 程式碼如下:
import pymongo
MONGO_URL = 'localhost' # 指定ip地址,localhost本地地址
MONGO_DB = 'taobao' # 指定資料庫名
MONGO_TABLE = 'iPad' # 指定資料表名(在mongodb中叫做集合)
client = pymongo.MongoClient(MONGO_URL) # 建立一個MONGODB連線物件
db = client[MONGO_DB] # 連線到MONGO_DB資料庫
def save_to_mongo(result): # 將資料匯入到資料庫中
try:
if db[MONGO_TABLE].insert(result): # 如果在MONGO_DB中插入資料成功,執行print語句
print('儲存成功')
except Exception:
print('儲存失敗')
END…
全部程式碼如下:
from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from pyquery import PyQuery as pq
import time
import pymongo # 匯入pymongo庫,與mongodb互動
browser = webdriver.Firefox() # 建立火狐瀏覽器物件
wait = WebDriverWait(browser, 10) # 建立等待物件,最大等待時間10s,超過10s丟擲TimeOutException異常
MONGO_URL = 'localhost' # 指定ip地址,localhost本地地址
MONGO_DB = 'taobao' # 指定資料庫名
MONGO_TABLE = 'iPad' # 指定資料表名(在mongodb中叫做集合)
def search(url): # 獲取商品的總頁數
try:
browser.get(url) # 訪問url
browser.maximize_window() # 最大化瀏覽器
sum = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '#mainsrp-pager > div > div > div > div.total')))
# 等待總頁數的加載出現
return int(sum.text[1:-2])
# 返回總頁數
except TimeoutException:
search(url)
def index_page(page): # 換頁,跳轉正第page頁
try:
if page > 1:
input = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,'#mainsrp-pager > div > div > div > div.form > input')))
# 等待輸入框加載出現,並選取
submit = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,'#mainsrp-pager > div > div > div > div.form > span.btn.J_Submit')))
# 等待確定按鈕加載出現(element_to_be_clickable可點選元素,來確定是按鈕元素)
input.clear()
# 清除輸入框內容
input.send_keys(page)
# 將要跳轉的頁數輸入到輸入框中
submit.click()
# 點選確定按鈕
wait.until(EC.text_to_be_present_in_element((By.CSS_SELECTOR, '#mainsrp-pager > div > div > div > ul > li.item.active > span'), str(page)))
# 選擇高亮的頁碼數,判斷它是否等於我們所跳轉的頁數
wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '#mainsrp-itemlist .items .item')))
# 等待商品資訊的載入
get_products() # 獲取商品資訊
except TimeoutException:
index_page(page)
def get_products():
# 用pyquery解析網頁
html = browser.page_source
doc = pq(html)
items = doc('#mainsrp-itemlist .items .item').items() # items()得到一個可遍歷的生成器
for item in items:
product = {
'image': item('.pic').find('img').attr('data-src'),
'price': item('.price').text(),
'deal': item('.deal-cnt').text()[:-3], # 擷取第一個字元至倒數第三個字元
'location': item('.location').text()
}
print(product)
save_to_mongo(product) # 將提取到的資訊儲存到MongoDB資料庫中
client = pymongo.MongoClient(MONGO_URL) # 建立一個MONGODB連線物件
db = client[MONGO_DB] # 連線到MONGO_DB資料庫
# 資料匯入資料庫中
def save_to_mongo(result):
try:
if db[MONGO_TABLE].insert(result): # 如果在MONGO_DB中插入資料成功,執行print語句
print('儲存成功')
except Exception:
print('儲存失敗')
def main():
try:
url = 'https://s.taobao.com/search?q=iPad'
total = search(url)
for i in range(1, total + 1):
index_page(i)
except Exception: # Exception 異常的父類
print('error!')
if __name__ == '__main__':
main()