美文网首页Python 爬虫专栏Python爬虫网络爬虫
Python爬虫日记六:Selenium+xpath+bs4爬取

Python爬虫日记六:Selenium+xpath+bs4爬取

作者: 梅花鹿数据rieuse | 来源:发表于2017-05-19 22:39 被阅读1375次

    一:前言

    上周末非常开心,第一次去北京然后参见了zealer和夸克浏览器的联合线下沙龙会议,和大家交流很多收获很多,最让我吃惊的是他们团队非常年轻就有各种能力,每个人都很强。一个结论:我要继续努力!
    贴上我们的合影,我很帅!:)

    zealer&夸克浏览器.jpg
    夸克浏览器合影.JPG

    这次爬虫是使用selenium来模拟输入关键字(我是测试输入各种图书)然后把全部页数的相关的商品数据保存到mongodb,期间遇到各种问题,很多网站不是很容易就一次可以把网页解析好,很轻松的提取数据。这个亚马逊就是有点怪,这次是提取商品的名称,图片地址,价格,时间,因为我的初始目的是出入有关图书的关键字,所以时间就是图书出版时间。

    关于‘python’关键字如图所示,爬取了300条数据。


    mongodb数据.png

    二:运行环境

    • IDE:Pycharm
    • Python3.6
    • Selenium 3.4.0
    • pymongo 3.3.0
    • BeautifulSoup 4.5.3

    三: 爬虫中重要(keng)的部分

    • 商品的时间使用Beautifulsoup是提取不出来的,使用正则表达式也搞不定,我最后用xpath才提取出来
    • 每个商品框架都是独立id,没有使用共同的class,所以要想获取他们使用正则表达式挺合适的
    • 因为商品的名称,图片地址,价格这三个是使用beautifulsoup提取的,而时间是用的xpath提取,要想把他们一起装入一个字典中然后写入mongodb就需要用到zip这个函数了。
      像这样的处理两个列表一起迭代for item, time in zip(content, date)

    四:实战代码

    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.ui import WebDriverWait
    from selenium import webdriver
    from bs4 import BeautifulSoup
    import lxml.html
    import pymongo
    import re
    
    MONGO_URL = 'localhost'
    MONGO_DB = 'amazon'
    MONGO_TABLE = 'amazon-python'
    SERVICE_ARGS = ['--load-images=false', '--disk-cache=true']
    KEYWORD = 'python'
    client = pymongo.MongoClient(MONGO_URL)
    db = client[MONGO_DB]
    
    browser = webdriver.PhantomJS(service_args=SERVICE_ARGS)
    # browser = webdriver.Firefox()
    wait = WebDriverWait(browser, 10)
    browser.set_window_size(1400, 900)
    
    
    def search():
        print('正在搜索')
        try:
            browser.get('https://www.amazon.cn/')
            input = wait.until(
                EC.presence_of_element_located((By.CSS_SELECTOR, '#twotabsearchtextbox'))
            )
            submit = wait.until(
                EC.element_to_be_clickable((By.CSS_SELECTOR, '#nav-search > form > div.nav-right > div > input')))
            input.send_keys(KEYWORD)
            submit.click()
            total = wait.until(
                EC.presence_of_element_located((By.CSS_SELECTOR, '#pagn > span.pagnDisabled')))
            get_products()
            print('一共' + total.text + '页')
            return total.text
        except TimeoutException:
            return search()
    
    
    def next_page(number):
        print('正在翻页', number)
        try:
            wait.until(EC.text_to_be_present_in_element(
                (By.CSS_SELECTOR, '#pagnNextString'), '下一页'))
            submit = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, '#pagnNextString')))
            submit.click()
            wait.until(EC.text_to_be_present_in_element(
                (By.CSS_SELECTOR, '.pagnCur'), str(number)))
            get_products()
        except TimeoutException:
            next_page(number)
    
    
    def get_products():
        try:
            wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '#s-results-list-atf')))
            html = browser.page_source
            soup = BeautifulSoup(html, 'lxml')
            doc = lxml.html.fromstring(html)
            date = doc.xpath('//*[@class="s-result-item  celwidget "]/div/div[2]/div[1]/span[2]/text()')
            content = soup.find_all(attrs={"id": re.compile(r'result_\d+')})
            for item, time in zip(content, date):
                product = {
                    'title': item.find(class_='s-access-title').get_text(),
                    'image': item.find(class_='s-access-image cfMarker').get('src'),
                    'price': item.find(class_='a-size-base a-color-price s-price a-text-bold').get_text(),
                    'date': time
                }
                save_to_mongo(product)
                print(product)
        except Exception as e:
            print(e)
    
    
    def save_to_mongo(result):
        try:
            if db[MONGO_TABLE].insert(result):
                print('存储到mongodb成功', result)
        except Exception:
            print('存储到mongodb失败', result)
    
    
    def main():
        try:
            total = int(search())
            for i in range(2, total + 1):
                next_page(i)
        except Exception as e:
            print('出错啦', e)
        finally:
            browser.close()
    
    
    if __name__ == '__main__':
        main()
    

    五:总结

    这次学习的东西还是很多,selenium用的模块很多,也利用了无头浏览器PhantomJS的不加载图片和缓存。爬取数据的时候使用了不同的方式,并用zip函数一起迭代保存为字典成功导入到mongodb中。
    贴出我的github地址,我的爬虫代码和学习的基础部分都放进去了,有喜欢的朋友一起学习交流吧!github.com/rieuse/learnPython

    相关文章

      网友评论

        本文标题:Python爬虫日记六:Selenium+xpath+bs4爬取

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