首先初始化一些变量
# -*- 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