Python抓取淘宝店铺并存入MongoDB数据库

在上一篇文章Python采集淘宝商品并存入MongoDB数据库中,使用了微博账号登陆淘宝采集数据的方式。但这种方法爬取了十几页之后就可能出现验证码,且手动滑动滑块验证码之后还不一定能验证通过,十分影响效率。

这次介绍另一种更强大一些的方法。首先人工登陆淘宝,登陆信息会被记录在谷歌浏览器用户数据User Data文件夹中。这个文件夹位于C盘用户→AppData→Local→Google→Chrome文件夹下。例如,我的电脑这个文件夹的完整路径为C:\Users\Lenovo\AppData\Local\Google\Chrome\User Data。

将这个User Data文件夹复制到抓取淘宝店铺Python文件(TaoBaoShopSpider.py)所在的同一文件夹下,如下图所示。然后在TaoBaoShopSpider.py文件中设置--user-data-dir属性,指向User Data文件夹,即:

chrome_options.add_argument('--user-data-dir=User Data')
数据.png

为什么--user-data-dir不直接指向C:\Users\Lenovo\AppData\Local\Google\Chrome\User Data文件夹,而非得复制一份呢?这是因为直接指向会出现“selenium.common.exceptions.InvalidArgumentException: Message: invalid argument: user data directory is already in use, please specify a unique value for --user-data-dir argument, or don't use --user-data-dir”的错误,导致代码不能正常运行。

完整代码如下:

import pymongo,time,random
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 pyquery import PyQuery as pq
from urllib.parse import quote

MONGO_URL = 'localhost'
MONGO_DB = 'shops'
MONGO_COLLECTION = 'zongzi'
KEYWORD = '粽子'
MAX_PAGE = 100
client = pymongo.MongoClient(MONGO_URL)
db = client[MONGO_DB]

chrome_options = webdriver.ChromeOptions()
chrome_options.add_experimental_option('excludeSwitches', ['enable-automation'])
chrome_options.add_experimental_option('useAutomationExtension', False)
# chrome_options.add_argument('--headless')
# chrome_options.add_argument('--user-data-dir=C:\\Users\\Lenovo\\AppData\\Local\\Google\\Chrome\\User Data')
chrome_options.add_argument('--user-data-dir=User Data')
browser = webdriver.Chrome(chrome_options=chrome_options)
browser.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {
    'source': 'Object.defineProperty(navigator, "webdriver", {get: () => undefined})'
})

wait = WebDriverWait(browser, 30)

def slide_down(second):
    for i in range(int(second / 0.1)):
        js = "var q=document.documentElement.scrollTop=" + str(300 + 200 * i)
        browser.execute_script(js)
        time.sleep(random.uniform(0.2, 0.4))
    time.sleep(0.2)

def get_page(page):
    print('正在爬取第', page, '页')
    try:
        url = 'https://shopsearch.taobao.com/search?q=' + quote(KEYWORD)
        print(url)
        browser.get(url)
        if page > 1:
            input = wait.until(
                EC.presence_of_element_located((By.CSS_SELECTOR, '#shopsearch-pager div.form > input')))
            submit = wait.until(
                EC.element_to_be_clickable((By.CSS_SELECTOR, '#shopsearch-pager div.form > span.btn.J_Submit')))
            slide_down(2.1)
            input.clear()
            input.send_keys(page)
            submit.click()
            time.sleep(random.uniform(1, 2))
        wait.until(
            EC.text_to_be_present_in_element((By.CSS_SELECTOR, '#shopsearch-pager li.item.active > span'), str(page)))

        slide_down(2.1)
        # wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '#list-container .list-item .item-bottom')))
        wait.until(EC.text_to_be_present_in_element((By.CSS_SELECTOR, '#list-container .list-item .list-info .info-sum'),'件宝贝'))
        time.sleep(random.uniform(1, 2))
        get_shops()
    except TimeoutException:
        print('遇到验证码,需要休息下!')
        time.sleep(15)
        get_page(page)

def get_shops():
    html = browser.page_source
    doc = pq(html)
    items = doc('#list-container .list-item').items()
    for item in items:
        shop = {
            'shoptitle': item.find('h4 a').text(),  #店铺名称
            'shopimg': item.find('.list-img a img').attr('src'),  #店铺图片
            'seller': item.find('.shop-info-list a').text(),  #卖家名称
            'sales': item.find('.info-sale em').text(),  #销量
            'products': item.find('.info-sum em').text(),  #宝贝数量
            'goodcomt': item.find('.good-comt').text()  #好评率
        }
        print(shop)
        save_to_mongo(shop)


def save_to_mongo(result):
    try:
        if db[MONGO_COLLECTION].insert(result):
            print('存储到MongoDB成功')
    except Exception:
        print('存储到MongoDB失败')

def main():
    for i in range(1, MAX_PAGE + 1):
        get_page(i)
        time.sleep(random.uniform(1, 2.5))
    browser.close()

if __name__ == '__main__':
    main()

经测试,这种方法可以至少顺利抓取3个搜索词的结果即300个页面,出现验证码的概率远少于微博登录的方式,而验证通过的概率远高于微博登录的方式。同样的,上一篇采集淘宝商品也可以用这种方式,抓取效率更高。

这篇文章设置了付费阅读,主要是测试下微信公众号付费阅读功能。当然,不付费也不影响获取主要内容,只是隐藏了回复关键词获取代码这部分。

PS:如果想获得这份代码,关注公众号【Python加SEO做增长】后台回复关键词【淘宝店铺】即可获得这份代码。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,607评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,239评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,960评论 0 355
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,750评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,764评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,604评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,347评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,253评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,702评论 1 315
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,893评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,015评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,734评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,352评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,934评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,052评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,216评论 3 371
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,969评论 2 355