爬取淘寶美食前100頁的title顺又,image,location等并存到mongodb上
selenium python 官網(wǎng):http://selenium-python.readthedocs.io/
http://selenium-python-zh.readthedocs.io/en/latest/
程序在 windows10 下執(zhí)行
首先安裝各種模塊和庫:
- 安裝Selenium伊群,pip install selenium
它是自動(dòng)化測(cè)試工具。支持各種瀏覽器策精,包括 Chrome舰始,Safari,F(xiàn)irefox 等主流界面式瀏覽器咽袜,安裝一個(gè)Seleium驅(qū)動(dòng)丸卷,我安裝的是谷歌 webdriver.Chrome(),這是驅(qū)動(dòng)地址:https://npm.taobao.org/mirrors/chromedriver/2.34/(國(guó)內(nèi)的源)
有界面的自動(dòng)化瀏覽器只適合測(cè)試询刹,總不能爬取的時(shí)候一直開著一個(gè)瀏覽器吧谜嫉,PhantomJS 是無界面的瀏覽器萎坷, 用 Google 瀏覽器測(cè)試完后就換成這個(gè),
下載地址:http://phantomjs.org/
運(yùn)行時(shí)出現(xiàn) warnings.warn('Selenium support for PhantomJS has been deprecated, please us 沐兰, 搜了一下是說 Selenium 以后不再支持 PhantomJS , 百度上說舊版的 PhantomJS 可以使用哆档,試了還是不行,就直接換成了 Google 的 chromedriver.exe
- 下載地址是 https://npm.taobao.org/mirrors/chromedriver/
下載后的 chromedriver.exe 文件要在程序中導(dǎo)入所在的路徑住闯,見 browser
我用的 Google Chrome 是 32位的 66.0 瓜浸,下載的 chromedriver.exe 是 2.37 的,運(yùn)行成功比原。
將下載的 chromedriver.exe 文件拖動(dòng)到python安裝目錄下插佛,使得 python 可以找得到這個(gè)文件就可以了。
安裝 Pyquery, pip install pyquery
pyquery 類似 jquery 的用法量窘,有許多的方法和函數(shù)雇寇,可以精確定位網(wǎng)頁中的元素,屬于解析 html 網(wǎng)頁的庫绑改。安裝 pymongo, pip install pymongo
python 調(diào)用 mongodb谢床,需要 pymongo 驅(qū)動(dòng)
由于在電腦上安裝完 mongoDB 一直連接不上,總是 failed 厘线,所幸就在虛擬機(jī)上安裝 mongoDB 识腿,在虛擬機(jī)上又跑不動(dòng)那么多程序,只能把數(shù)據(jù)存到 text 文檔造壮,學(xué)習(xí)一下使用 mongoDB 渡讼。
- 安裝 mongoDB 網(wǎng)址:http://blog.csdn.net/polo_longsan/article/details/52430539
程序開始
import json
import re
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.chrome.options import Options
from selenium.common.exceptions import TimeoutException
from pyquery import PyQuery as pq
#import pymongo
#引入頭文件,注釋掉的是引入 mongodb耳璧,因?yàn)殡娔X連接不上mongodb成箫,就不用了
#client = pymongo.MongoClient(MONGO_URL)
#db = client[MONGO_DB]
函數(shù) search 前的是設(shè)置 browser, search 抓取首頁和發(fā)送淘寶搜索關(guān)鍵詞
chrome_options = Options()
#設(shè)置為 headless 模式,注釋掉就會(huì)彈出Google瀏覽器窗口顯示
chrome_options.add_argument('--headless')
browser = webdriver.Chrome(executable_path=(r'C:\Users\libai\AppData\Local\Google\Chrome\Application\chromedriver.exe'), chrome_options=chrome_options)
#browser 中的地址是所下載的 chromdriver.exe 所放的位置旨枯,我把它放到了 chrome 安裝目錄下
wait = WebDriverWait(browser, 10)
def search():
try:
browser.get('https://www.taobao.com/')
#用的是 CSS 選擇器
inputs = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "#q")))
submit = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "#J_TSearchForm > div.search-button > button")))
inputs.send_keys("美食")
submit.click()
total = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "#mainsrp-pager > div > div > div > div.total")))
result = int(re.compile("(\d\d\d)").search(total.text).group(1))
get_products()
return result
except TimeoutException:
search()
#一旦超時(shí)蹬昌,就重新調(diào)用 search
在抓取完頁面后, 跳下一頁攀隔,直接在 inputs 中輸入跳轉(zhuǎn)的頁面皂贩,點(diǎn)擊確定就行了
def next_page(page_number):
try:
inputs = 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")))
inputs.clear()
inputs.send_keys(page_number)
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_number)))
get_products()
except TimeoutException:
next_page(page_number)
獲取頁面詳細(xì)信息,使用 pyquery 提取頁面中的元素
def get_products():
wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "#mainsrp-itemlist .items .item")))
#等待頁面加載完成
html = browser.page_source
doc = pq(html)
#.items() 函數(shù)屬性是提取多個(gè)
items = doc('#mainsrp-itemlist .items .item').items()
for item in items:
product = {
'image' : item.find('.pic .pic-link .img').attr("src"),
'price' : item.find('.row .price').text().replace('\n', '') ,
'deal' : item.find('.row .deal-cnt').text()[:-3],
'title' : item.find('.title').text().replace('\n', ' '),
'shop' : item.find('.shop').text(),
'location' : item.find('.location').text()
}
print('---------------------------------')
save_to_text(product)
存儲(chǔ)到 text 文件中昆汹,不加 encoding="UTF-8" 明刷,會(huì)報(bào)編碼錯(cuò)誤, json 格式更加便利于存取
def save_to_text(product):
try:
with open("product.txt", "a", encoding="UTF-8") as f:
f.write(json.dumps(product) + '\n')
print("寫入成功", product)
except:
print("寫入失敗", product)
主程序
def main():
with open('product.txt', "w", encoding="UTF-8") as f:
print("新建product.txt文件成功")
total = search()
print("一共有 " + str(total) + " 頁")
for i in range(2, total):
print("跳轉(zhuǎn)到第 %d 頁" %i)
next_page(i)
browser.close()
if __name__ == "__main__":
main()
從 text 文件中讀取满粗,再寫入到 mongoDB 數(shù)據(jù)庫中
import json
import pymongo
MONGO_URL = "localhost"
MONGO_DB = "taobao"
MONGO_TABLE = 'product'
client = pymongo.MongoClient(MONGO_URL)
db = client[MONGO_DB]
def openandsave(filename):
file = open(filename)
while 1:
lines = file.readlines(100000)
if not lines:
break
for line in lines:
print(json.loads(line))
save_to_mongodb(json.loads(line))
print('-----------------')
file.close()
def save_to_mongodb(result):
try:
if db[MONGO_TABLE].insert(result):
print('存儲(chǔ)到MONGODB成功', result)
except:
print('存儲(chǔ)到MONGODB失敗', result)
def main():
filename = "product.txt"
openandsave(filename)
if __name__ == '__main__':
main()
看起來不是很對(duì)辈末,有些細(xì)節(jié)的地方?jīng)]有調(diào)整好
數(shù)據(jù)庫圖片