Python selenium练习:爬取京东商品搜索结果

Selenium是一个自动化测试工具,利用它可以驱动浏览器执行特定的动作(具体的配置或使用可以百度)。我用的谷歌浏览器,先在镜像下载谷歌浏览器版本对应的驱动版本https://npm.taobao.org/,下下来直接解压就能用了。

代码只是个简单的练习,对于异常情况没有过多的处理,也没有代理、登录、验证什么的,只是能用(或许网络不好的话需要把超时和睡眠时间加长一点点)。另外,对于数据的解析我也写得很简单,导致商品名中的换行符也没去掉,以及商品有套装的情况也没处理(导致所有套装项的商品名和价格合并在了一起)。我的处理流程就是,根据搜索内容一页一页的解析,将解析结果存到文本里,判断翻页栏的总页数和当前页数进行翻页,递归直到最后一页。

还有个没解决的问题就是,因为搜索结果会动态加载,需要往下拉滚动条,我也不知道啥时候才算是全部加载完了,看别人博客写的是第一次滑到底是30个,等加载完再滑到底就有60个。目前我是循环几次往下拉滚动条,但是不能保证一定加载完了。

代码如下:

from selenium import webdriver
from selenium.webdriver.common.by import  By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait

from pyquery import  PyQuery

import time
import json

# 数据写入文本
def write_to_file(content,filepath):
    with open(filepath,'a',encoding='utf-8') as f:
        f.write(json.dumps(content,ensure_ascii=False)+'\n')


# 解析爬出来的商品列表信息
def parse_jd_html(html):
    #搜索出来的商品列表包裹在ul.gl-warp(为什么是warp不是wrap)下的li.gl-item中
    #作为测试,只取出书名和价格
    doc=PyQuery(html)
    items=doc('ul.gl-warp li.gl-item').items()
    for item in items:
        yield{
            'name':item.find('.p-name a em').text().strip(),
            'price':item.find('.p-price strong i').text()
        }

#根据keys进行爬取相关信息
def search_by_keys(keys):
    #edge浏览器不用去下载驱动也能使用,我的版本为EdgeHTML 18
    #browser=webdriver.Edge()
    #谷歌浏览器需要下载驱动,可以去镜像下载对应版本https://npm.taobao.org/
    #解压出来exe随便放哪里都能用

    #chrome_options=webdriver.ChromeOptions()
    #chrome_options.add_argument('--headless') #无界面模式
    #browser=webdriver.Chrome(r'C:\Users\1992\AppData\Local\Google\Chrome\Application\chromedriver.exe',chrome_options=chrome_options)
    browser=webdriver.Chrome(r'C:\Users\1992\AppData\Local\Google\Chrome\Application\chromedriver.exe')
    wait=WebDriverWait(browser,20) #设置几秒超时时间

    try:
        browser.get('https://www.jd.com/') #京东首页
        #print(browser.current_url)
        #print(browser.get_cookies())
        #print(browser.page_source)

        # until当某条件成立则继续执行,注意后面方法参数传元祖
        # 等待搜索框加载完
        input=wait.until(EC.presence_of_element_located((By.ID,'key')))
        # 等待搜索按钮可点击
        #enter=wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,'.form button')))
        input.clear()
        input.send_keys(keys)
        input.send_keys(Keys.ENTER)

        # 爬取数据
        def crawling_data():
            # 动态加载的太多,多滚动几次
            for i in range(3):
                # 等待底部翻页栏加载完
                wait.until(EC.presence_of_element_located((By.ID, 'J_bottomPage')))
                # 滚动条滚到底部
                browser.execute_script('window.scrollTo(0,10000)') #document.body.scrollHeight
                # 发现如果没加载完的话有个id为J_scroll_loading的div
                # 等待加载元素消失
                wait.until_not(EC.presence_of_element_located((By.ID,'J_scroll_loading')))
                time.sleep(1)


            page_count=wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,'#J_bottomPage .p-skip b')))
            page_input = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '#J_bottomPage .p-skip .input-txt')))
            page_button = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, '#J_bottomPage .p-skip a')))

            #解析并存储
            for item in parse_jd_html(browser.page_source):
                write_to_file(item,keys+'.txt')

            count=int(page_count.text)
            current=int(page_input.get_attribute('value'))
            print('完成:',current,'/',count)
            # 爬下一页
            if count>current:
                page_input.clear()
                page_input.send_keys(str(current+1))
                #print(current+1)
                page_button.click()
                crawling_data()

        crawling_data()

    except Exception as e:
        print('exception:',e)
    else:
        print('success')
    finally:
        #close只会关闭当前页面,quit会退出驱动并且关闭所关联的所有窗口,最后执行完以后就关闭。
        browser.quit()
        print('browser quit')

if __name__ == '__main__':
    search_by_keys('C++书籍')

爬取结果:

Over,不得不说selenium真是个好东西~~ 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龚建波

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值