1 #使用selenium+Carome/phantomJS模拟浏览器爬取淘宝商品信息 2 # 思路: 3 # 第一步:利用selenium驱动浏览器,搜索商品信息,得到商品列表 4 # 第二步:分析商品页数,驱动浏览器翻页,并得到商品信息 5 # 第三步:爬取商品信息 6 # 第四步:存储到mongodb 7 import re 8 from selenium import webdriver 9 from selenium.common.exceptions import TimeoutException 10 from selenium.webdriver.common.by import By 11 from selenium.webdriver.support.ui import WebDriverWait 12 from selenium.webdriver.support import expected_conditions as EC 13 from pyquery import PyQuery as pq 14 from config import * 15 import pymongo 16 17 client = pymongo.MongoClient(MONGO_URL) 18 db = client[MONGO_DB] 19 # 声明浏览器对象,这里定为Chrome 20 # browser = webdriver.Chrome() 21 # 声明浏览器对象,可以使用PhanttomJS,这是无界面浏览器,可以设置不加载图片,启用缓存等加快速度 22 browser = webdriver.PhantomJS(service_args=SERVICE_ARGS) # 在配置文件设定参数 23 24 browser.set_window_size(1400, 900) # 默认的窗口比较小,为避免影响操作需设定 25 26 # 传入搜索关键词并搜索 27 # 在这里,需要等待搜索框与搜索按钮加载出来完毕,方可传入关键词,并点击搜索 28 wait = WebDriverWait(browser, 10) # 表示给browser浏览器一个10秒的加载时间 29 30 def search(): 31 print('正在搜索……') 32 try: 33 # 驱动浏览器打开网页 34 browser.get('https://www.taobao.com/') 35 input = wait.until(EC.presence_of_element_located((By.ID, 'q'))) # 表示在规定时间内等待,直到id为q的元素加载出来,注意传入的是元组 36 input.send_keys(KEYWORDS) 37 # 同样的道理,搜索的按钮也需要等待,直到按钮加载出来,是可以点击的 38 button = wait.until(EC.element_to_be_clickable( 39 (By.CSS_SELECTOR, '#J_TSearchForm > div.search-button > button'))) # 表示规定时间内,搜索按钮是否是可点击的 40 button.click() 41 #页面加载完成后,找到总页数 42 total = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,'#mainsrp-pager > div > div > div > div.total'))) 43 44 get_product() 45 return total.text 46 except TimeoutException: 47 return search() 48 49 # # 得到当前页面的html 50 # html = browser.page_source 51 52 def next_page(page_number): 53 print('正在翻页……') 54 try: 55 #等待页码框加载完成 56 input = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,'#mainsrp-pager > div > div > div > div.form > input'))) 57 58 #等待确定按钮可点击,然后点击 59 button = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,'#mainsrp-pager > div > div > div > div.form > span.btn.J_Submit'))) 60 61 # 清空并输入页码 62 input.clear() 63 input.send_keys(page_number) 64 65 button.click() 66 67 #检查当前页是否切换 text_to_be_present_in_element 某个元素文本包含某文字 68 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))) 69 70 get_product() 71 except TimeoutException: 72 next_page(page_number) 73 74 75 def get_product(): 76 wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,'#mainsrp-itemlist > div'))) 77 html = browser.page_source 78 doc = pq(html) 79 lis = doc('#mainsrp-itemlist .items .item').items() 80 for item in lis: 81 product={ 82 'title':item.find('.title').text(),#find方法是为了嵌套找出来,防止遗漏 83 'price':item.find('.price').text(), 84 'deal':item.find('.deal-cnt').text(), 85 'shop':item.find('.shop').text(), 86 'location':item.find('.location').text(), 87 'image':item.find('.pic .img').attr('src') 88 } 89 print(product) #return product #终于找到问题所在了,谨慎使用return啊,因为函数遇到return就会返回!,不再进行循环了 90 save_to_mongo(product) 91 92 def save_to_mongo(result): 93 try: 94 if db[MONGO_TABLE].insert(result): 95 print('保存到MONGODB成功',result) 96 97 except Exception: 98 print('保存到MONGODB失败',result) 99 100 def main():101 102 try:103 total = search()104 total = int(re.compile(r'(\d+)').search(total).group(1))#正则提取页数105 for page_number in range(2,total + 1):106 next_page(page_number)107 108 except Exception:109 print('出错了')110 111 finally:112 browser.close()113 114 if __name__=='__main__':115 main()116 117 #配置文件118 MONGO_URL = 'localhost'119 MONGO_DB = 'taobao'120 MONGO_TABLE = 'product'121 122 SERVICE_ARGS =['--disk-cache=true','--load-images=false']123 KEYWORDS = '美食'