运用selenium爬取淘宝商品信息并保存在本地文件夹或MongoDB数据库

首先初始化一些变量

# -*- coding: utf-8 -*-

'''
@Time    : 2019/11/6 15:02
@Author  : yoos
@FileName: 17.selenium爬取淘宝并保存在MongoDB.py
@Software: PyCharm
 
'''
#from requests import options
import json
import os

from selenium import webdriver
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.wait import  WebDriverWait
from urllib.parse import quote
from pyquery import PyQuery as pq
import pymongo
import logging

KEYWORD = 'macbook'

weibo_usename = '你的微博账号'
weibo_password = '你的微博密码'

MAX_PAGE = 10   #爬取最大页数

MONGO_URL = 'localhost'
MONGO_DB = 'taobaoShouJi'
MONGO_COLLECTION = 'products'
client = pymongo.MongoClient(MONGO_URL)
db = client[MONGO_DB]

url = 'https://s.taobao.com/search?q=' + quote(KEYWORD)
options = webdriver.ChromeOptions()
# options.add_argument('headless')            #这功能是让浏览器在后台运行。
options.add_argument('disable-infobars')  # add_arguments添加启动参数,这个disable-infobars功能是隐藏Chrome正在受自动软件的控制的框。。。
browser = webdriver.Chrome(options=options)
wait = WebDriverWait(browser, 30)
browser.get(url)``

因为采用selenium直接登陆淘宝会有滑块验证,其实滑块验证也可以利用代码带写,但是相对麻烦一些。这里采用第三方登陆,这样就不会有滑块验证了。代码如下:

def login():
            #从微博第三方登陆,免去滑块验证

            # 等待 密码登录选项 出现
            password_login = wait.until(
                EC.presence_of_element_located((By.CSS_SELECTOR, '.qrcode-login > .login-links > .forget-pwd')))
            password_login.click()

            # 等待 微博登录选项 出现
            weibo_login = wait.until(
                EC.presence_of_element_located((By.CSS_SELECTOR, '.weibo-login')))
            weibo_login.click()

            browser.find_element_by_css_selector('.username > .W_input').send_keys(weibo_usename)
            browser.find_element_by_css_selector('.password > .W_input').send_keys(weibo_password)
            browser.find_element_by_css_selector('.btn_tip > a > span').click()

接下来就是控制页面跳转的函数

ef index_page(page):
    '''
    提取索引页
    '''
    print('正在爬取第{}页...'.format(page))
    try:
        if page > 1:
            input = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,'#mainsrp-pager .input.J_Input')))     #页码框
            botton = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,'#mainsrp-pager div.form > span.btn.J_Submit')))         #跳转按钮
            input.clear()
            input.send_keys(page)
            botton.click()
            wait.until(
                EC.text_to_be_present_in_element((By.CSS_SELECTOR,'#mainsrp-pager li.item.active'),str(page)))   #判断是否高亮,即是否成功跳转页面,只有高亮部分才有这个
            wait.until(
                EC.presence_of_element_located((By.CSS_SELECTOR, '.m-itemlist .items .item')))   #等待我们要爬取页面信息的全部节点刷新出来!!
            get_product()
    except TimeoutException:
        print('请求超时...重新爬取')
        index_page(page)

在接下就是解析页面的函数,直接用CSS选择器,简单粗暴的干就完事了

def get_product():
    '''
    解析商品信息
    :return:
    '''
    html = browser.page_source
    doc = pq(html)
    items = doc('#mainsrp-itemlist .items .item').items()
    for item in items:
        product = {
            'img': item.find('.pic .img').attr('data-src'),
            'price': item.find('.price').text(),
            'deal' : item.find('.deal-cnt').text(),
            'title': item.find('.title').text(),
            'shop': item.find(('.shop')).text(),
            'loction': item.find('.location').text()
        }
        print(product)
        #save_to_mongo(product)
        save_to_local(product)

再下面就是爬取数据的储存,安装有MongoDB数据库的朋友可以直接保存如MongoDB,没有也没啥,保存在本地即可,这里给出两种保存策略,选择一个就好啦~

保存到MongoDB数据库
def save_to_mongo(result):
    try:
        if db[MONGO_COLLECTION].insert_one(result):    #db[MONGO_COLLECTION].inser(result)成功返回1,失败返回0
            print('储存到MongoDB成功')
    except Exception as e:
        logging.exception(e)
        print('储存在MongoDB失败')
def save_to_local(result):
    if not os.path.exists(KEYWORD + '商品信息'):
        os.mkdir(KEYWORD + '商品信息')
    with open(KEYWORD + '商品信息' + '/' + KEYWORD + '.txt','a',encoding = 'utf-8') as f:
        f.write(json.dumps(result,ensure_ascii=False) + '\n')
        #print json.dumps('中国')
        #"\u4e2d\u56fd"   这是因为json.dumps 序列化时对中文默认使用的ascii编码.想输出真正的中文需要指定ensure_ascii=False

最后面就是把以上代码统筹执行的主函数了。
这里就不写了~
我把完整代码放入了github上,有兴趣的朋友可以去下载下来玩,上面还会实时更新一些爬虫实例,记得star哦~
https://github.com/liyunlongaaa/SpiderDemo

你可能感兴趣的:(倔强的小爬虫)