Selenium+Python

提前准备

  • Chrome 浏览器 查看版本号
  • chromedriver 查看版本号,需要和浏览器版本号一致
  • selenium 地址 通过 pip3 install selenium 安装
  • Python3 环境 自行安装。 windows 下载好安装包一路下一步,记得勾中添加环境变量

使用

原理

  • selenium 控制 chromedriver 来驱动 Chrome 浏览器
# 引入 webdriver
from selenium import webdriver
# 保存 chromedriver 路径
PATH = 'D:\softwares\chromedriver.exe'
# 接收 webdriver 驱动
driver = webdriver.Chrome(PATH)
# 获取目标地址
driver.get('目标地址')
# 通过 xpath 获取目标文本
total_nums = driver.find_element_by_xpath('//*[@id="content"]/div[1]/div[2]/h2/span')
# 打印爬取目标的文本内容
print(total_nums.text)
# 退出驱动 节省内存
driver.quit()

爬取大量数据思路

  • 查看目标网站信息
    • 分析
      • 总数据 十五万多
      • 最多100 个分页,每页最多 30 数据,一次最多只能爬取 3000
    • 处理
      • 细分查询条件
        • 按照位置细分
          • 按照位置细分查看
            • /heping/
              -/nankai/
            • 。。。
            • /ninghe/
            • 后面所有位置在最后的路径上替换对应位置的拼音
          • 搜索数据仍多余 3000 条
        • 在位置细分的基础上再增加搜索条件
          • 按售价细分
            • /heping/p1/
            • /heping/p2/
            • 。。。
            • /heping/p7/
            • 按售价在 url 末尾增加 p1 - p7
        • 在以上基础下发现还有总数居多余 3000 的情况
          • 按房型细分
            • /jinnan/l1p1/
            • /jinnan/l2p1/
            • 。。。
            • /jinnan/l6p1/
            • 房型 l1 -l6
        • 如果再有超过 3000 条数据,继续以此思路往下查找,此处不做过多拆解
      • 分页查询
        • 每一页不同的显示规律,最多到 100页
          • /jinnan/l1l6p7/
          • /jinnan/pg2l1l6p7/
          • /jinnan/pg3l1l6p7/
          • 。。。
          • 分页 pg1 - pg100
      • 具体详情页查询
        • /jinnan/l1l6p7/
          • 有 26 条数据
          • 每条数据的标题都带着具体的详情页 url
            • /101113895984.html
            • /101113405120.html
            • 。。。
        • 获取每一页的所有数据的详情页,即可获得所有房源的具体信息
      • 最终信息查询
        • 遍历所有详情页,去获取想要保存的数据
  • 结果处理
    • 分析完毕,开始目标

代码演示

import time
from selenium import webdriver
from lxml import etree
# 大量数据演示
city_url = '目标地址'
PATH = 'D:\softwares\chromedriver.exe'
driver = webdriver.Chrome(PATH)

# 获取具体位置的 url
def get_locate_url():
    range_urls = {
    
    }
    driver.get(city_url)
    html = driver.page_source
    selector = etree.HTML(html)
    for i in range(0, 19):
        a_href = str(selector.xpath('/html/body/div[3]/div/div[1]/dl[2]/dd/div[1]/div/a[' + str(i + 1) + ']/@href')[0])
        a_name = str(selector.xpath('/html/body/div[3]/div/div[1]/dl[2]/dd/div[1]/div/a[' + str(i + 1) + ']/text()')[0])
        range_url = 'https://tj.lianjia.com' + a_href
        range_urls[a_name] = range_url
    return range_urls

# 获取分条件查找的 url
def get_locate_detail_url():
    range_urls = get_locate_url()
    range_price_urls = {
    
    }
    for key in range_urls:
        range_url = range_urls[key]
        part_range_price_url = []
        total_urls = []
        for i in range(1, 7):
            range_price_url = range_url + 'l' + str(i)
            part_range_price_url.append(range_price_url)
        for i in part_range_price_url:
            for j in range(1, 8):
                range_price_url = i + 'p' + str(j)
                total_urls.append(range_price_url)
        range_price_urls[key] = total_urls
    return range_price_urls

# 获取分页详情
# 爬取完全部需要一定时间 展示下即可
def get_page_url():
    locate_detail_url = get_locate_detail_url()
    total_urls = []
    for key in locate_detail_url:
        locate_detail_urls = locate_detail_url[key]
        for url in locate_detail_urls:
            driver.get(url)
            # 等待资源加载完成
            time.sleep(2)
            html = driver.page_source
            selector = etree.HTML(html)
            # 获取每一页有多少数据
            house_nums = int(selector.xpath('//*[@id="content"]/div[1]/div[2]/h2/span/text()')[0])
            # 借助 python 整数类型特性
            # 每页最多 30 条
            # 如果取余为0 说明数据刚好够每页30条
            # 如果余数不为0 说明末尾页数据不足30 整体页数要 + 1
            yushu = house_nums % 30
            if yushu == 0:
                page_size = int(house_nums / 30)
            else:
                page_size = int(house_nums / 30) + 1
            print('数据量' + str(house_nums), '余数' + str(yushu), '商' + str(int(house_nums / 30)), '分页数' + str(page_size))
            for i in range(0, page_size):
                if i == 0:
                    last_url = url
                else:
                    split_url = url.split('/')
                    url_detail_search = split_url[5]
                    last_url = url.replace(url_detail_search, 'pg' + str(i + 1) + url_detail_search)
                print(last_url)
                total_urls.append(last_url)
    return total_urls

# 模拟数据
# 获取具体详情页
# 模拟获取 total_urls
def get_detail_urls():
    # total_urls = get_page_url()
    total_urls = ['目标地址']
    all_details = []
    for url in total_urls:
        driver.get(url)
        time.sleep(2)
        html = driver.page_source
        selector = etree.HTML(html)
        for i in range(0, 30):
            try:
                # 数据量超过能爬到的数量就会报错
                # 报错即跳出循环读取下一页数据
                final_url = selector.xpath('//*[@id="content"]/div[1]/ul/li[' + str(i + 1) + ']/div[1]/div[1]/a/@href')[0]
                print(final_url)
                all_details.append(final_url)
            except Exception:
                print('没有这么多页数据,跳出结束循环')
                break
    return all_details

# 获取详细信息
def get_detail_info():
    detail_urls = get_detail_urls()
    all_details = []
    for url in detail_urls:
        driver.get(url)
        time.sleep(2)
        html = driver.page_source
        selector = etree.HTML(html)
        total_price = selector.xpath('//*[@class="total"]/text()')[0]
        unit_price = selector.xpath('//*[@class="unitPriceValue"]/text()')[0]
        apartment_name = selector.xpath('//*[@class="communityName"]/a[1]/text()')[0]
        range_area = selector.xpath('//*[@class="info"]/a[2]/text()')[0]
        print(total_price, unit_price, apartment_name, range_area)
        all_details.append({
    
    'total_price': total_price, 'unit_price': unit_price, 'apartment_name': apartment_name,
                            'range_area': range_area})
    driver.quit()
    return all_details

猜你喜欢

转载自blog.csdn.net/it_xcr/article/details/123735777
今日推荐