一:前言
上周末非常開(kāi)心,第一次去北京然后參見(jiàn)了zealer和夸克瀏覽器的聯(lián)合線下沙龍會(huì)議,和大家交流很多收獲很多,最讓我吃驚的是他們團(tuán)隊(duì)非常年輕就有各種能力舅桩,每個(gè)人都很強(qiáng)哥放。一個(gè)結(jié)論:我要繼續(xù)努力!
貼上我們的合影峭弟,我很帥!:)
這次爬蟲(chóng)是使用selenium來(lái)模擬輸入關(guān)鍵字(我是測(cè)試輸入各種圖書(shū))然后把全部頁(yè)數(shù)的相關(guān)的商品數(shù)據(jù)保存到mongodb跷乐,期間遇到各種問(wèn)題浅侨,很多網(wǎng)站不是很容易就一次可以把網(wǎng)頁(yè)解析好,很輕松的提取數(shù)據(jù)订歪。這個(gè)亞馬遜就是有點(diǎn)怪眼虱,這次是提取商品的名稱,圖片地址舶赔,價(jià)格,時(shí)間,因?yàn)槲业某跏寄康氖浅鋈胗嘘P(guān)圖書(shū)的關(guān)鍵字焕窝,所以時(shí)間就是圖書(shū)出版時(shí)間垃沦。
關(guān)于‘python’關(guān)鍵字如圖所示,爬取了300條數(shù)據(jù)休涤。
二:運(yùn)行環(huán)境
- IDE:Pycharm
- Python3.6
- Selenium 3.4.0
- pymongo 3.3.0
- BeautifulSoup 4.5.3
三: 爬蟲(chóng)中重要(keng)的部分
- 商品的時(shí)間使用Beautifulsoup是提取不出來(lái)的,使用正則表達(dá)式也搞不定糯钙,我最后用xpath才提取出來(lái)
- 每個(gè)商品框架都是獨(dú)立id嗅蔬,沒(méi)有使用共同的class吴趴,所以要想獲取他們使用正則表達(dá)式挺合適的
- 因?yàn)樯唐返拿Q,圖片地址趋厉,價(jià)格這三個(gè)是使用beautifulsoup提取的,而時(shí)間是用的xpath提取翼馆,要想把他們一起裝入一個(gè)字典中然后寫(xiě)入mongodb就需要用到zip這個(gè)函數(shù)了魔吐。
像這樣的處理兩個(gè)列表一起迭代for item, time in zip(content, date)
四:實(shí)戰(zhàn)代碼
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium import webdriver
from bs4 import BeautifulSoup
import lxml.html
import pymongo
import re
MONGO_URL = 'localhost'
MONGO_DB = 'amazon'
MONGO_TABLE = 'amazon-python'
SERVICE_ARGS = ['--load-images=false', '--disk-cache=true']
KEYWORD = 'python'
client = pymongo.MongoClient(MONGO_URL)
db = client[MONGO_DB]
browser = webdriver.PhantomJS(service_args=SERVICE_ARGS)
# browser = webdriver.Firefox()
wait = WebDriverWait(browser, 10)
browser.set_window_size(1400, 900)
def search():
print('正在搜索')
try:
browser.get('https://www.amazon.cn/')
input = wait.until(
EC.presence_of_element_located((By.CSS_SELECTOR, '#twotabsearchtextbox'))
)
submit = wait.until(
EC.element_to_be_clickable((By.CSS_SELECTOR, '#nav-search > form > div.nav-right > div > input')))
input.send_keys(KEYWORD)
submit.click()
total = wait.until(
EC.presence_of_element_located((By.CSS_SELECTOR, '#pagn > span.pagnDisabled')))
get_products()
print('一共' + total.text + '頁(yè)')
return total.text
except TimeoutException:
return search()
def next_page(number):
print('正在翻頁(yè)', number)
try:
wait.until(EC.text_to_be_present_in_element(
(By.CSS_SELECTOR, '#pagnNextString'), '下一頁(yè)'))
submit = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, '#pagnNextString')))
submit.click()
wait.until(EC.text_to_be_present_in_element(
(By.CSS_SELECTOR, '.pagnCur'), str(number)))
get_products()
except TimeoutException:
next_page(number)
def get_products():
try:
wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '#s-results-list-atf')))
html = browser.page_source
soup = BeautifulSoup(html, 'lxml')
doc = lxml.html.fromstring(html)
date = doc.xpath('//*[@class="s-result-item celwidget "]/div/div[2]/div[1]/span[2]/text()')
content = soup.find_all(attrs={"id": re.compile(r'result_\d+')})
for item, time in zip(content, date):
product = {
'title': item.find(class_='s-access-title').get_text(),
'image': item.find(class_='s-access-image cfMarker').get('src'),
'price': item.find(class_='a-size-base a-color-price s-price a-text-bold').get_text(),
'date': time
}
save_to_mongo(product)
print(product)
except Exception as e:
print(e)
def save_to_mongo(result):
try:
if db[MONGO_TABLE].insert(result):
print('存儲(chǔ)到mongodb成功', result)
except Exception:
print('存儲(chǔ)到mongodb失敗', result)
def main():
try:
total = int(search())
for i in range(2, total + 1):
next_page(i)
except Exception as e:
print('出錯(cuò)啦', e)
finally:
browser.close()
if __name__ == '__main__':
main()
五:總結(jié)
這次學(xué)習(xí)的東西還是很多,selenium用的模塊很多垃瞧,也利用了無(wú)頭瀏覽器PhantomJS的不加載圖片和緩存。爬取數(shù)據(jù)的時(shí)候使用了不同的方式碳默,并用zip函數(shù)一起迭代保存為字典成功導(dǎo)入到mongodb中。
貼出我的github地址顶燕,我的爬蟲(chóng)代碼和學(xué)習(xí)的基礎(chǔ)部分都放進(jìn)去了,有喜歡的朋友一起學(xué)習(xí)交流吧!github.com/rieuse/learnPython