夜鹰教程网-程序员的加油站
 当前位置:文章中心 >> Python
使用selenium爬取商城数据代码
夜鹰教程网 来源:www.yyjcw.com 日期:2020-3-28 9:58:07
使用selenium爬取商城数据代码
from selenium import webdriver
import random
import time
import csv
import re
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC#条件判断
from selenium.webdriver.support.wait import WebDriverWait#等待

class TestSpider(object):
    def __init__(self):
        self.url = '这里是目标网站链接'
        self.error = []
    #进入一级页面
    def get_page(self):
        options = webdriver.ChromeOptions()
        # 添加无界面参数
        options.add_argument('--headless')
        self.browser = webdriver.Chrome(options=options)
        self.browser.get(self.url)
        print('已启动浏览器1')
        self.browser.maximize_window()
        self.browser.implicitly_wait(8)

        self.browser2 = webdriver.Chrome(options=options)
        self.browser2.implicitly_wait(3)
        print('已启动浏览器2')
        WebDriverWait(self.browser,5).until(EC.element_to_be_clickable((By.XPATH,'//*[@id="pageTWrap"]/div[4]/ul/li[2]/a'))).click()


    #遍历一级页面各个产品节点
    def xunhuan_one_page(self):
       
     
        i = 1
        #如果出错了,重新爬取,可以在这里加入上次那个产品所在的页数,位置,代码有待补充


        while True:

            list = self.browser.find_elements_by_xpath('//div[@id="proList"]//div[@index]')  # 产品节点
            if i <= int(len(list)):

                try:
                    num = list[i-1].find_element_by_xpath('.//div[@class="pro-sold"]//span[@class="num"]')
                    page_one = self.browser.find_element_by_xpath('//div[@class="filter-page"]/span').text
                    page_one = re.split('\s|\/', page_one)[1]

                    list[i-1].find_element_by_xpath('.//div[@class="photo"]//img').click()

                    print('已进入第{}个产品节点'.format(i))
                    i = i + 1
                    time.sleep(random.randint(7,8))
                    try:
                        self.two_page()

                    except:
                        print('\033[1;35;0m ****************************** \033[0m')
                        a = ['第{}页第{}个产品爬取失败'.format(page_one,i-1)]
                        self.error.append(a)
                        print(a[0])
                        print('\033[1;35;0m ****************************** \033[0m')
                        self.save_error(a)
                        # self.error.append(a)
                    time.sleep(random.randint(2,3))

                    while True:
                        try:
                            MainContent = self.browser.find_element_by_xpath('//div[@class="mainout"]').get_attribute(
                                'id')
                            break
                        except:
                            self.browser.back()
                            time.sleep(random.randint(2,3))
                except:
                    i = i+1
            else:
                if self.browser.page_source.find('unnext') == -1:
                    self.browser.find_element_by_xpath('//div[@class="filter-page"]//a[@class="next"]').click()
                    i = 1#翻页了,归1
                    one_page = self.browser.find_element_by_xpath('//div[@class="page"]/span/b').text
                    print('一级页面第{}页'.format(one_page))
                    time.sleep(random.randint(1,2))
                else:
                    break
        print(self.error)

        self.browser.quit()
        # print(self.error)

    #二级页面的一些操作
    def two_page(self):
        #尝试爬取二级页面的某些信息,加入了判断语句,10次内拿到数据则停止
        m = 1
        while True:
            try :
                if m <= 10 :

                    product = self.browser.find_element_by_xpath('//*[@id="colLeft"]/div[1]/div[1]/div/div[1]/h2').text
                    page = self.browser.find_element_by_xpath('//*[@id="transactionHistory"]/div/div[5]/div/span/strong[2]').text
                    three_url = self.browser.find_element_by_xpath('//div[@id="transactionHistoryWarp"]').get_attribute(
                        'init-src')
                    time.sleep(random.randint(0,1))
                    m = m+1
                    if page != None and three_url != None and product != None:
                        print(product)
                        print(three_url)
                        break
                    else:
                        continue
                else:
                    break

            except :
                self.browser.find_element_by_xpath('//li[@id="ctab-transactionHistory"]/span').click()  # 点击历史记录
                time.sleep(random.randint(0, 1))
      
        #拿到的链接不完整,需要自己拼接
        three_url_list = re.split('\?', three_url)
        three_url = three_url_list
        r_three_url = '这里是目标网站初始链接' + three_url[0] + '?act=pageload&appid=dh&page={}&' + three_url[-1] + '&lang=en'

        info_list = [['买家', '产品名称', '购买数量', '购买日期', '买方地址']]
        self.three_parse_page(product, info_list, page, r_three_url)




    #与parse_page还有save_page结合爬取某一个产品节点的所有历史交易记录
    def three_parse_page(self,product,info_list,page,r_three_url):
        j = 1
        while True:
            if j <= int(page) :

                self.browser2.get(r_three_url.format(j))
                self.parse_page(info_list)

                print('三级页面第{}页爬取成功'.format(j))
                j = j+1
                time.sleep(random.randint(1,2))
            else:
                print('三级页面最后一页爬取成功')
                try:
                    self.save_page(product,info_list)
                    print('产品节点信息存储成功')
                except:
                    self.save_page2(product,info_list)
                    print('产品节点信息存储成功')
                time.sleep(random.randint(1,2))
                break

    #三级页面爬取函数
    def parse_page(self,info_list):

        tran_list = self.browser2.find_elements_by_xpath(
            '//div[@class="transaction-list"]//ul'
        )

        for tran in tran_list:
            info_two = tran.text.split('\n')
            country = tran.find_element_by_xpath('.//li[@class="col1"]//img').get_attribute('src')
            country_list = re.split('\.|\/',country)
            cou = country_list[-2]
            info_two.append(cou)#买家,产品名称,数量,日期,买家地址
            info_list.append(info_two)

        time.sleep(random.randint(1,2))

     #保存三级页面的数据
    def save_page(self,product,info_list):
        with open('{}.csv'.format(product), 'a', newline='') as f:
            for rt in info_list:
                writer = csv.writer(f)
                writer.writerow([rt[0].strip(), rt[1].strip(), rt[2].strip(), rt[3].strip(), rt[4]])
   
    #有些product作为文件名由于有'/'这个符号会出错,所以写个新的函数去除'/'            
    def save_page2(self,product,info_list):
        product = re.split('\/',product)[0]
        with open('{}.csv'.format(product), 'a', newline='') as f:
            for rt in info_list:
                writer = csv.writer(f)
                writer.writerow([rt[0].strip(), rt[1].strip(), rt[2].strip(), rt[3].strip(), rt[4]])
    
    #凡是爬取失败的产品,报错信息存下来(页数,第几个商品)
    def save_error(self,a):
        with open('error.csv', 'w', newline='') as f:
            writer = csv.writer(f)
            writer.writerow([a[0].strip()])


    def main(self):
        self.get_page()
        self.xunhuan_one_page()

if __name__ == '__main__':
    spider = TestSpider()
    spider.main()

复制链接 网友评论 收藏本文 关闭此页
上一条: Python 优缺点  下一条: Windows消息机制详解
夜鹰教程网成立于2008年,目前已经运营了将近 13 年,发布了大量关于 html5/css3/C#/asp.net/java/python/nodejs/mongodb/sql server/android/javascript/mysql/mvc/easyui/vue/echarts原创教程。 我们一直都在坚持的是:认证负责、一丝不苟、以工匠的精神来打磨每一套教程,让读者感受到作者的用心。我们默默投入的时间,确保每一套教程都是一件作品,而不是呆板的文字和视频! 目前我们推出在线辅导班试运营,模式为一对一辅导,教学工具为QQ。我们的辅导学科包括 java 、android原生开发、webapp开发、商城开发、C#和asp.net开发,winform和物联网开发、web前端开发,但不仅限于此。 普通班针对的是国内学员,例如想打好基础的大学生、想转行的有志青年、想深入学习的程序员、想开发软件的初学者或者业余爱好者等。 就业办针对即将毕业上岗的大四学生,或者打算转行的初级开发工程师。 留学生班针对的是在欧美、加拿大、澳洲、日本、韩国、新加坡等地留学的中国学子,目的是让大家熟练地掌握编程技能,按时完成老师布置的作业,并能顺利地通过考试。 详细咨询QQ:1416759661   夜鹰教程网  基于角色的权限管理系统(c-s/b-s)。
  夜鹰教程网  基于nodejs的聊天室开发视频教程
  夜鹰教程网  Git分布式版本管理视频教程
  夜鹰教程网  MVC+EasyUI视频教程
  夜鹰教程网  在线考试系统视频教程
  夜鹰教程网  MongoDB视频教程。
  夜鹰教程网 Canvas视频教程
  夜鹰教程网 报表开发视频教程
  热点推荐
C++从零开始学编程
C++ 数组array与vector的比较
VC、VC++、C++、C它们有什么区别
SQLite在VC下的使用
五种区别C++内存分配的方法
用Cint解析C++脚本
C打开文件的追加参数
C++ Builder 访问 USB 口的方法
C++中强制转换函数总结
为C++脚本加入新元素
C/C++编程中无所不在的指针概念
C++程序调用数据库的方法
内存泄漏是编程中常常见到的一个问…
C++中指针入门的最好的文章
C++编译错误解决方法
  最近更新
Python操作EXCEL表格
Python 优缺点
使用selenium爬取商城数据代码
Windows消息机制详解
SQLite在VC下的使用
五种区别C++内存分配的方法
VC的dll进行profile
C打开文件的追加参数
C/C++编程中无所不在的指针概念
C++从零开始学编程
VC、VC++、C++、C它们有什么区别
为C++脚本加入新元素
用Cint解析C++脚本
C++ Builder 访问 USB 口的方法
C++中强制转换函数总结

关于我们 | 网站建设 | 技术辅导 | 常见问题 | 联系我们 | 友情链接

夜鹰教程网 版权所有 www.yyjcw.com All rights reserved 备案号:蜀ICP备08011740号3