这篇文章主要介绍如何用selenium抓取淘宝指定种类的所有商品列表 通过读取商品列表利用requests抓取天猫店铺的所有评论信息保存到mongodb

    开始写爬虫代码前,我们需要先思考下你需要得到哪些信息

在这里,我需要得到的是淘宝指定商品的信息,包括价格、店铺、销量、标题、卖家、地址,还有就是各商品的所有用户评价信息,抓取到这些信息后可以方便我们后续的数据分析

最后面有我的完整代码

首先打开淘宝,审查元素

python爬虫天猫评论 selenium爬取淘宝评论_爬虫

 

 

然后检查网页源代码,看网页源代码里是否含有商品的信息,在这里ctrl+f搜索某商品的价格,这里发现商品价格信息之类的都在一个script标签里,说明淘宝的商品列表都是通过js渲染出来的

python爬虫天猫评论 selenium爬取淘宝评论_淘宝_02

 

那么我们可以用正则提取网页的商品信息,也可以用selenium,这里为了方便,我就用selenium了

下面是抓取商品信息的代码,如果不懂的话这里有视频详细解析,代码也源自这位博主,感谢他,我只是稍作修改

python爬虫天猫评论 selenium爬取淘宝评论_python_03

python爬虫天猫评论 selenium爬取淘宝评论_python爬虫天猫评论_04

#导入需要的库
import re
from pyquery import PyQuery as pq  #解析库
from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

browser = webdriver.Chrome()
#等待变量
wait = WebDriverWait(browser,10)

#模拟搜索
def search():
    try:
        browser.get('https://www.taobao.com/')#打开淘宝首页
        tb_input = wait.until(
            EC.presence_of_element_located((By.CSS_SELECTOR, '#q'))
        )#等待输入框加载完成
        search_btn = wait.until(
            EC.element_to_be_clickable((By.CSS_SELECTOR, '#J_TSearchForm > div.search-button > button'))
        )#等待搜索按钮加载完成
        tb_input.send_keys('口红')#输入框中传入你需要搜索的商品
        search_btn.click()#点击搜索
        total = wait.until(
            EC.presence_of_element_located((By.CSS_SELECTOR, '#mainsrp-pager > div > div > div > div.total'))
        )#加载完成,获取页数元素
        get_products()
        return total.text#获取元素中的文本
    except TimeoutException:
        return search()#若发生异常,重新调用自己

#获取商品信息
def get_products():
    wait.until(
        EC.presence_of_element_located((By.CSS_SELECTOR, '#mainsrp-itemlist .items .item'))
    )#等待商品信息加载完成,商品信息的CSS选择器分析HTML源码得到
    html = browser.page_source#得到页面HTML源码

    doc = pq(html)#创建PyQuery对象
    items = doc('#mainsrp-itemlist .items .item').items()#获取当前页所有商品信息的html源码
    for item in items:
    #这里为了后面获取商品的评论信息,需要知道商品id以及店铺id        
    product = {
            # 'image':item.find('.pic .img').attr('src'),
            'itemid':item.find('.shop .shopname').attr('data-nid'),
            'sellerid':item.find('.shop .shopname').attr('data-userid'),
            'url':item.find('.title .J_ClickStat').attr('href'),
            'price':item.find('.price').text(),
            'deal':item.find('.deal-cnt').text()[:-3],
            'title':item.find('.title').text(),
            'seller':item.find('.shop').text(),
            'location':item.find('.location').text()
        }
        print(product)

#翻页函数
def next_page(page_number):
    try:
        page_input = wait.until(
            EC.presence_of_element_located((By.CSS_SELECTOR, '#mainsrp-pager > div > div > div > div.form > input'))
        )#等待翻页输入框加载完成
        confirm_btn = wait.until(
            EC.element_to_be_clickable((By.CSS_SELECTOR, '#mainsrp-pager > div > div > div > div.form > span.btn.J_Submit'))
        )#等待确认按钮加载完成
        page_input.clear()#清空翻页输入框
        page_input.send_keys(page_number)#传入页数
        confirm_btn.click()#确认点击翻页
        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))
        )#确认已翻到page_number页
        get_products()
    except TimeoutException:
        next_page(page_number)#若发生异常,重新调用自己

def main():
    total = search()#获取商品页数,字符串类型
    total = int(re.compile('(\d+)').search(total).group(1))#利用正则表达式提取数字,并强制转换为int类型
    for i in range(2, total+1):
        next_page(i)
    browser.close()

if __name__ == '__main__':
    main()

View Code

接下来我们就是将数据保存到数据库了

 

首先保存到mongodb的函数代码如下

python爬虫天猫评论 selenium爬取淘宝评论_python_03

python爬虫天猫评论 selenium爬取淘宝评论_python爬虫天猫评论_04

import pymongo

#创建数据库以及数据表
client = pymongo.MongoClient('localhost',27017)
dataname = client['tb_kouhon']
table = dataname['goods_info']

def save_to_mongoDB(product):
    try:
        if table.insert(product):
            print('存储到MongoDB成功',product)
    except Exception:
        print('存储到MongoDB失败',product)

View Code

 

将该函数插入到get_products()中

python爬虫天猫评论 selenium爬取淘宝评论_python爬虫天猫评论_07

 

运行一下,淘宝每页有48个商品,总共100页,除掉重复的数据,发现和我们得到4000多条数据基本一致

 

python爬虫天猫评论 selenium爬取淘宝评论_python_08

 

接下来在练习一下保存数据到mysql

首先打开mysql终端创建数据库及数据表

python爬虫天猫评论 selenium爬取淘宝评论_python_03

python爬虫天猫评论 selenium爬取淘宝评论_python爬虫天猫评论_04

#创建数据库
mysql> create database tb;
Query OK, 1 row affected (0.00 sec)

创建数据表
mysql> use tb;
Database changed
mysql> create table tb_inf(
    -> id smallint unsigned auto_increment primary key,
    -> itemid varchar(30),
    -> sellerid varchar(30),
    -> url varchar(200),
    -> price varchar(20),
    -> deal varchar(20),
    -> title varchar(200),
    -> seller varchar(50),
    -> location varchar(50)
    -> );
Query OK, 0 rows affected (0.22 sec)

View Code

 

 

然后创建存储到mysql的函数,这里要特别注意一点,利用pymysql插入数据到mysql是字符字段要有双引号括起来,不然会报错,这个非常重要,血泪般的教训==

python爬虫天猫评论 selenium爬取淘宝评论_python_03

python爬虫天猫评论 selenium爬取淘宝评论_python爬虫天猫评论_04

def save_to_mysql(product):
    sql = '''INSERT INTO tb_info(itemid,sellerid,url,price,deal,title,seller,location) VALUES (%s,%s,"%s","%s",%s,"%s","%s","%s")'''
    try:
        cursor.execute(sql % (product['itemid'],product['sellerid'],product['url'],product['price'],product['deal'],product['title'],product['seller'],product['location']))
        conn.commit()
    except:
        conn.rollback()

View Code

 

ok,接下来运行下,爬几分钟就ok了,和上次爬的相比少了几十条数据,不过无关紧要了

python爬虫天猫评论 selenium爬取淘宝评论_评论_13

 

接下来我们就是开始抓取淘宝各商品的评论了

这里因为淘宝商品有反爬策略,频繁爬取需要登录,还要输入验证码

所以在这里只演示爬取天猫商品的评论

首先我们随便打开一个天猫商品的全部评论,打开network,翻几页评论

python爬虫天猫评论 selenium爬取淘宝评论_python爬虫天猫评论_14

 

 

点开response,可以发现里面全是json数据,这个list_detail_rate.htm?里面就是就是我们需要的数据

接下来我们看一下他的request url

这里我试了下,url可以简写成

https://rate.tmall.com/list_detail_rate.htm?itemId=546724870335&sellerId=3170729146¤tPage=4

访问下试试,如我们所料,评论都在这

在看下简化后url的构成,可以分成三部分itemId,sellerId,currentPage分别表示商品id,店铺id,评论页数

接下来就简单了

首先我们把上面爬取到的商品信息读取出来

python爬虫天猫评论 selenium爬取淘宝评论_python_03

python爬虫天猫评论 selenium爬取淘宝评论_python爬虫天猫评论_04

import pymongo

client = pymongo.MongoClient('localhost',27017)
dataname = client['tb_kouhon']
table = dataname['goods_info']
allgoods = []
for i in table.find({}):
    goodsdic = {'itemid':i['itemid'],
    'sellerid':i['sellerid']}
    allgoods.append(goodsdic)

print(allgoods)

View Code

然后构造爬取函数,构造函数前先要弄清它的json数据是怎么镶套的,弄清楚就好写代码了

python爬虫天猫评论 selenium爬取淘宝评论_python_03

python爬虫天猫评论 selenium爬取淘宝评论_python爬虫天猫评论_04

def crawl_rank(itemid,sellerid):
    url = 'https://rate.tmall.com/list_detail_rate.htm?itemId={}&sellerId={}¤tPage={}'
    maxpage = get_page(itemid,sellerid)
    print(maxpage)
    for page in range(1,maxpage+1):
        try:
            header = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.91 Safari/537.36'}
            response = requests.get(url.format(itemid,sellerid,page),headers= header)
            html = response.text
            formaljson = html[15:]
            jsondata = json.loads(formaljson)
            items = jsondata['rateList']
            for item in items:
                goodsrate = {'date':item['rateDate'],
                             'sku':item['auctionSku'],
                             'usernick':item['displayUserNick'],
                             'content':item['rateContent']}
                save_to_mongo(goodsrate)
        except:
            continue

View Code

然后是获取总页数的函数和存储到mongo数据库的函数,这里的总页数也可以在json中获取到

python爬虫天猫评论 selenium爬取淘宝评论_python_03

python爬虫天猫评论 selenium爬取淘宝评论_python爬虫天猫评论_04

def save_to_mongo(goodsrate):
    try:
        if table2.insert(goodsrate):
            print('存储到MongoDB成功',goodsrate)
    except Exception:
        print('存储到MongoDB失败',goodsrate)

def get_page(itemid,sellerid):
    try:
        url = 'https://rate.tmall.com/list_detail_rate.htm?itemId={}&sellerId={}¤tPage={}'
        header = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.91 Safari/537.36'}
        response = requests.get(url.format(itemid,sellerid,0), headers=header)
        html = response.text
        formaljson = html[15:]
        jsondata = json.loads(formaljson)
        return jsondata['paginator']['lastPage']
    except:
        return get_page(itemid,sellerid)

def main():
    for i in range(len(allgoods)):
        goods = allgoods[i]
        print(goods)
        crawl_rank(goods['itemid'],goods['sellerid'])

View Code

运行main()试试看

python爬虫天猫评论 selenium爬取淘宝评论_python爬虫天猫评论_21

 

 这里有我的完整代码:github

到这里我们就大公告成了,以后有时间在研究下淘宝店铺的评论抓取

如果你对我的代码有什么疑问或者改进的地方,可以在评论里指出,大家互相交流才能取得进步,谢谢大家^^