Python爬取指定关键字的淘宝商品信息-Selenium

我们在新浪微博的抓取中,已经实现了ajax抓取的操作,详情请戳链接:https://blog.csdn.net/qq_29027865/article/details/83239316

但是对于一些ajax获取的数据,有些接口比较复杂,包含动态的参数等,如果没有办法及时分析出参数的规律,那么此时使用Selenium来抓取也是一个不错的选择。

Python爬取指定关键字的淘宝商品信息-Selenium_第1张图片

一.搜索关键字

Python爬取指定关键字的淘宝商品信息-Selenium_第2张图片

(1)首先引入selenium的库:

from selenium import webdriver

(2)使用webdriver生成一个浏览器驱动:

browser = webdriver.Chrome()
#browser = webdriver.PhantomJS()

注:需要提前将driver.exe添加到环境变量,下载路径请戳:

https://download.csdn.net/download/qq_29027865/10328885

https://download.csdn.net/download/qq_29027865/10328884

 (3)请求淘宝首页:

browser.get('https://www.taobao.com')

(4)因为加载页面需要时间,为了防止加载时间过长而出现报错,在这里加上一个判断加载是否成功的操作:

通过selenium官方文档找到waits方法,详情戳:https://selenium-python.readthedocs.io/

Python爬取指定关键字的淘宝商品信息-Selenium_第3张图片

 

通过定位右键copy selector,可以得到输入框的css选择器的内容,同样方法获取到按钮的css选择器的内容,如下:

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

#定位等待使用presence_of_element_located
#定位点击使用element_to_be_clickable
#容易出现超时错误,加上超时异常来作为判断

def search():
    try:
        browser.get('https://www.taobao.com')
        # 判断是否加载成功
        input = wait.until(
            EC.presence_of_element_located((By.CSS_SELECTOR, "#q"))
        )
        submit = WebDriverWait(browser,10).until(EC.element_to_be_clickable((By.CSS_SELECTOR,'#J_TSearchForm > div.search-button > button')))
        input.send_keys('手机')
        submit.click()
    except TimeoutException:
        return search()

二.分析页码及翻页:

Python爬取指定关键字的淘宝商品信息-Selenium_第4张图片

Python爬取指定关键字的淘宝商品信息-Selenium_第5张图片

通过分析淘宝商品的页面,

如果是通过直接点击下一页来遍历每页,会存在一个问题:

遍历到最后一页时,程序会因找不到下一页这个selector而选择异常退出,这是最好的情况。但是如果在爬取过程中出现了异常退出,这时也没有记录当前的页数,就无法继续爬取后续对应的页面了。还需要在点击下一页获取中做异常检测,整个流程相对复杂,因此这里我们呢采取第二种方法来获取页面。

Python爬取指定关键字的淘宝商品信息-Selenium_第6张图片

实现如下:

def next_page(page_number):
    try:
        input = wait.until(
            EC.presence_of_element_located((By.CSS_SELECTOR, "#mainsrp-pager > div > div > div > div.form > input"))
        )
        submit = WebDriverWait(browser, 10).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_products()
    except TimeoutException:
        next_page(page_number)

三.分析提取商品的内容

Python爬取指定关键字的淘宝商品信息-Selenium_第7张图片

根据商品信息的源码,我们可以看出:每个商品都是一个item,它们在id为'mainsrp-itemlist'下的items的列表中:

1.首先判定这个items是否加载成功:

wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,'#mainsrp-itemlist .items .item')))
    

2.通过pagesorce拿到网页源代码,并使用pyQyery来解析css;

3.获取商品值:attr获取属性值text()获取文本值,对于一些文本值,使用列表形式进行切割,[:-3]指从前面到倒数第三个:

def get_products():
    wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,'#mainsrp-itemlist .items .item')))
    # 通过page_source方法获取源代码
    html = browser.page_source
    # 初始化pyquery对象
    doc = pq(html)
    # 通过调用items的方法来得到一个生成器,遍历生成器,来逐个得到li节点的对象
    items = doc('#mainsrp-itemlist .items .item').items()
    for item in items:
        product = {
            'image': item.find('.pic .img').attr('src'),
            'price': item.find('.price').text(),
            'deal':item.find('.deal-cnt').text()[:-3],
            'title':item.find('.title').text(),
            'shop':item.find('.shop').text(),
            'location':item.find('.location').text()
        }
        print(product)

完整代码如下:

from selenium import webdriver
from selenium.common.exceptions import TimeoutException

from pyquery import  PyQuery as pq
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import re
browser = webdriver.Chrome()

browser.set_window_size(1400,900)

wait = WebDriverWait(browser,10)

# 翻页的两种方法:1.下一页;2.输入到某页后点击确定
# 判断高亮的数字

def search():
    print("正在搜索...")
    try:
        browser.get('https://www.taobao.com')
        # 判断是否加载成功
        input = wait.until(
            EC.presence_of_element_located((By.CSS_SELECTOR, "#q"))
        )
        submit = WebDriverWait(browser,10).until(EC.element_to_be_clickable((By.CSS_SELECTOR,'#J_TSearchForm > div.search-button > button')))
        input.send_keys('手机')
        submit.click()
        total = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,'#mainsrp-pager > div > div > div > div.total')))
        return total.text
    except TimeoutException:
        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 = WebDriverWait(browser, 10).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_products()
    except TimeoutException:
        next_page(page_number)

# 解析方法
def get_products():
    wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,'#mainsrp-itemlist .items .item')))
    # 通过page_source方法获取源代码
    html = browser.page_source
    # 初始化pyquery对象
    doc = pq(html)
    items = doc('#mainsrp-itemlist .items .item').items()
    for item in items:
        product = {
            'image': item.find('.pic .img').attr('src'),
            'price': item.find('.price').text().strip()[2:],
            'deal':item.find('.deal-cnt').text()[:-3],
            'title':item.find('.title').text(),
            'shop':item.find('.shop').text(),
            'location':item.find('.location').text()
        }
        print(product)


def main():
    try:
        total = search()
        # 提取出100的数字
        total = int(re.compile('(\d+)').search(total).group(1))
        for i in range(2,total+1):
            next_page(i)
    except Exception:
        print("出错啦~")
    finally:
        browser.close()

if __name__ == '__main__':
    main()

#     再加一个等待操作,这里实现得是分页得逻辑
#     total = wait.until(EC.presence_of_element_located(By.CSS_SELECTOR,'#mainsrp-pager > div > div > div > div.total'))
    # 返回内容

 

你可能感兴趣的:(Python爬虫)