美文网首页Python
python爬虫08-selenium爬取淘宝网商品(源码)

python爬虫08-selenium爬取淘宝网商品(源码)

作者: DKider | 来源:发表于2019-03-30 21:47 被阅读17次

    昨天之所以水了,是因为日更30天了,歇一歇,同时也是为了完成今天的这个爬虫,毕竟第一次使用selenium+chrome爬取网站。

    前两天写分析ajax爬虫,是分析了网站请求的参数、请求地址、上传的表单,模拟浏览器访问页面来的到源码,但是有时候ajax的参数非常多,而且经过加密,很难找到规律。这时候我们就需要使用selenium这个强大的库了,它可以控制浏览器,模拟人的操作,直接获取浏览器渲染完成后的页面源码,真正做到可见即可爬。

    不多说,让我们开始吧!
    selenium需要我们配合浏览器使用,它支持很多款浏览器,但是我更喜欢chrome,因为它调试起来更方便,就像很多前段程序猿也喜欢chrome一样,反正我不喜欢IE,让它当场去世吧!

    chromeDriver 也是必需品。下载下来后放在环境的script文件下。

    这次也是,还是剩下一小部分没完成,现在还没学习到。之后会完善。

    • 搜索商品后会直接跳到登录界面,所以我直接打开的登录界面,现在我只能扫码登陆,账号密码登陆会出滑动验证码,这在ChromeDriver里无法完成,我就直接等10s让我扫码登陆了。

    其实吧我感觉爬虫没什么好讲的,主要是对抗反爬机制能够给我带来快乐。这次淘宝的反爬很厉害。换页的速度不能太快,太快的话,到18页就会被要求进行滑动验证,但是由于浏览器问题,总是失败。所以我在换页之前用了10s的延时才能全部爬下来。

    一共爬了100页,我输入的‘ipad’,一共4404条数据,全部存在数据库中,方便以后使用:

    image.png 结果

    [图片上传失败...(image-e5e97b-1553952994597)]

    这次的程序中设计等待时间的概念,一个是隐式等待,一个是显示等待。
    隐式等待就是等待给定的时间,在寻找页面中的元素,如果时间到了还没加载出来,就报错,这一般用的少,但这次我也用了,在扫码登录的时候。
    显示等待是指如果再规定的时间内加载出来了,就获取节点,如果没有加载出来报错。

    代码不长,具体内容就不讲了,没意思。你爬虫遇到问题了,来对比下,找找不同,这样才能得到最大的进步,什么都直接说出来,就没有找答案的这个过程,也就没有任何的成就感,而且我写这个,只是我为了记录自己的学习过程。最终虽然得到了我想要的,但反爬机制没解决,感觉得到之后一切都变得索然无味。

    还有就是浏览器滑动验证这一点,这将是我接下来的学习方向,之后就可以为所欲为了。

    import re
    import time
    from selenium import webdriver
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    from pyquery import PyQuery as pq
    from config import *
    import pymongo
    
    # chrome_options = webdriver.ChromeOptions()
    # chrome_options.add_argument()
    browser = webdriver.Chrome()
    
    wait = WebDriverWait(browser, 10)
    client = pymongo.MongoClient(MONGODB_HOST, MONGODB_POST)
    db = client[MONGODB_DB]
    collection = db[MONGODB_COLLECTION]
    
    def login():
        print("正在登录")
        # 需要用手机淘宝扫二维码登录才能搜索
        browser.get(url='https://login.taobao.com')
        # 10s用来扫码登录
        browser.implicitly_wait(10)
    
    def search():
        print("正在查找",KEYWORD)
        try:
            input = wait.until(
                EC.presence_of_element_located((By.CSS_SELECTOR, "#q"))
            )
            submit = wait.until(
                EC.element_to_be_clickable((By.CSS_SELECTOR, "#J_TSearchForm > div.search-button > button"))
            )
            input.send_keys(KEYWORD)
            submit.click()
            total = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,
                                                        "#mainsrp-pager > div > div > div > div.total")))
            get_goods()
            return total.text
        except TimeoutError:
            return search()
    
    def next_page(page_number):
        print("正在换页", page_number)
        try:
            input = wait.until(
                EC.presence_of_element_located((By.CSS_SELECTOR, "#mainsrp-pager > div > div > div > div.form > input"))
            )
            submit = wait.until(
                EC.element_to_be_clickable(
                    (By.CSS_SELECTOR, "#mainsrp-pager > div > div > div > div.form > span.btn.J_Submit"))
            )
            input.clear()
            input.send_keys(page_number)
            submit.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)))
            get_goods()
        except Exception:
            next_page(page_number)
    
    
    def get_goods():
        try:
    
            wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,
                                                       '#mainsrp-itemlist .items '
                                                       '.item')))
            html = browser.page_source
            doc = pq(html)
            items = doc('#mainsrp-itemlist .items .item').items()
            for item in items:
                goods = {
                    '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(),
                    'location': item.find('.location').text()
                }
                save_to_mongodb(goods)
        except Exception:
            print("获取商品失败")
    
    def save_to_mongodb(result):
        try:
            if db[MONGODB_COLLECTION].insert_one(result):
                print("存储到数据成功", result)
        except Exception:
            print("存储到数据库失败", result)
    
    def main():
        login()
        total = search()
        total = int(re.compile('(\d+)').search(total).group(0))
        for i in range(2, total + 1):
            if i % 15 == 0:
                time.sleep(20)
            next_page(i)
    
    if __name__ == '__main__':
        main()
    
    

    在使用前一定要记得把该装的库都装了,数据库打开,网络通畅。

    得抓紧学习了,要赶在工大春招之前学完。

    之前在百度贴吧帮别人解决问题,这让我很开心,忘记了时间。所以今天晚了点。

    相关文章

      网友评论

        本文标题:python爬虫08-selenium爬取淘宝网商品(源码)

        本文链接:https://www.haomeiwen.com/subject/lvzsbqtx.html