python selenium实现下拉 爬取淘宝商品信息

之前爬取过一次淘宝的商品,直接使用slenium就可以直接爬取信息,这次又想再次爬取一下信息,发现每次爬取的信息都不全,纠结啊!

(一)首先,介绍下背景:

这次爬取的选择是手机。打开淘宝,搜索手机,可以发现每页商品共有48个,一共100页。

(二)流程介绍

首先确定使用的爬取方式(这里使用selenium),然后是页面分析,标签定位,最后确定信息的存储方式(这里为了方便直接打印), 最后的最后就是程序的编写了。

(三)程序编写

页面分析,标签定位这些就不再详细介绍了,直接说程序的编写了。编写好程序之后,就是运行了。然而运行的时候,发现了一个问题,每页提取出来的信息远远少于每页应该有的信息(每页是48个,这里却每次大约提取了一半左右)。最初以为是程序的问题,仔细检查了几遍之后,发现都是同样的问题。因此决定把获取的网页源代码下载下来看下:

html = browser.page_source
with open("taobao.txt",'w', encoding='utf-8') as f:
    f.write(html)

接下来查看源代码,

可以发现,有很大一部分商品信息没有加载出来

(四)问题分析

根据(三)可以发现,商品信息没有完全爬取的原因是:在页面信息没有完全加载的情况下,就已经把网页信息下载下来了。

接下来返回淘宝商品页面,可以发现,商品页面并不是一次加载完的。下拉面右边的进度条可以发现,在下拉的过程中,部分商品信息才加载出来。因此,可以确定要想把信息完全加载出来,还应该实现程序下拉,因此在原先程序中加入,下拉功能:
 

browser.execute_script('window.scrollBy(0, 1000)')

每次下来1000像素,经过测试,我的电脑只需要下拉5次就可以了,因此,下拉的全部代码如下:

while  True:
            if sroll_cnt < 5:
                browser.execute_script('window.scrollBy(0, 1000)')
                time.sleep(0.2)
                sroll_cnt += 1
            else:
                break

每次下来后,都暂停0.2s,给加载留下反应的时间,如果网络不好,这个时间还可以加长。经过测试,这样就可以把全部信息加载出来了。

(五)源码

下面就是全部的源码了,最后的结果没有进行存储,只是打印了出来。

from selenium import webdriver
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.wait import WebDriverWait
from urllib import parse
from bs4 import BeautifulSoup
import time


browser = webdriver.Firefox()
wait = WebDriverWait(browser, 30)

KEYWORD = '手机'
MaxPage = 100   #最大页数
count = 0  #控制变量
sroll_cnt = 0  #下拉控制次数
def html_get(page):
    """
        获取html生成
    """
    global sroll_cnt 
    print("正在",page,'页')
    url = "https://s.taobao.com/search?q=%E6%89%8B%E6%9C%BA"
    browser.get(url)
    try:
        """
            首先寻找输入框
        """
        input_p = wait.until(
            EC.presence_of_element_located((By.CSS_SELECTOR, '#spulist-pager .form>input')))
        submit_p = wait.until(
            EC.element_to_be_clickable((By.CSS_SELECTOR, '#spulist-pager .form>.btn')))

        input_p.clear()
        input_p.send_keys(page)
        submit_p.click()
   
        time.sleep(3)
        #browser.execute_script('window.scrollBy(0, document.body.scrollHeight)')
        while  True:
            if sroll_cnt < 5:
                browser.execute_script('window.scrollBy(0, 1000)')
                time.sleep(0.2)
                sroll_cnt += 1
            else:
                break
        sroll_cnt = 0   #复位

        print("开始等待")
        wait.until(
            EC.text_to_be_present_in_element((By.CSS_SELECTOR, '#spulist-pager .items .item.active>span'), str(page)))
        print("第一个等待已经结束")
        wait.until(
            EC.presence_of_element_located((By.CSS_SELECTOR, "#spulist-grid .grid-container #J_SPUBlankRow11 .grid-item .title-row")))
        
        get_product()   #转到获取商品页面
    except TimeoutException:
        print("超时")
        html_get(page)   #超时重新调用



def get_product():  
    """
        获取商品信息
    """
    global count
    html = browser.page_source  #获取商品xinxi
    soup = BeautifulSoup(html,'lxml')
    item_list = soup.select('#spulist-grid .grid-container .grid-item')
    if count < 1:
        with open('taobao.txt','w', encoding='utf-8') as f:
            f.write(html)
            count += 1

    print(len(item_list))
    for item in item_list:
        try:
            product = {
                "name":item.select('.title-row .product-title')[0].attrs['title']
            }
            print(product)
        except:
            pass

def main():
    for i in range(1, MaxPage+1):
        html_get(i)

if __name__ == '__main__':
    main()

猜你喜欢

转载自blog.csdn.net/qq_34246164/article/details/81637302