一、Excel操作

import openpyxl

# 写操作
# 1.获取工作簿对象(工作簿对应的就是一个excel文件)
# 新建(默认有一个工作表)
# work_book = openpyxl.Workbook()
# 打开
# work_book = openpyxl.load_workbook(文件路径)


# work_book = openpyxl.Workbook()
work_book = openpyxl.load_workbook('files/test2.xlsx')

# 2.获取所有的表的表名
all_names = work_book.sheetnames
print(all_names)

# 3.获取表
# sheet = work_book['Sheet']

# 4.新建表
# 工作簿对象.create_sheet(表名, 表的下标)
# work_book.create_sheet('学生表')
# work_book.create_sheet('学生表2', 0)

# 5.删除表
# 工作簿对象.remove(表对象)
# work_book.remove(work_book[表名])

# 6.表重命名
# sheet = work_book['学生表2']
# sheet = work_book.active
# sheet.title = 'Student'

# 7.写入数据到单元格
# 单元格对象.value   -   获取单元格中的内容
# 单元格对象.value = 新值   -   修改单元格中的内容
sheet = work_book['Student']

# 1)获取单元格方法一
# 工作表对象.cell(行号: int, 列号: int)
cell1 = sheet.cell(1, 1)
# 修改单元格中的内容
# cell1.value = '姓名'

cell2 = sheet['B1']
# cell2.value = '年龄'

# 清空单元格
cell2.value = ''


# 5.保存文件
work_book.save('./files/test2.xlsx')
import openpyxl

# 读操作
# 1.打开文件
wb = openpyxl.load_workbook('files/test1.xlsx')

# 2.获取工作表
# sheet = wb['学生表']
sheet = wb.active

# 3.获取单元格
# 1)获取单个单元格
# sheet.cell(行号, 列号)    -  行号和列号都是从1开始的数字
# sheet[位置信息]  - 位置信息是类似:'A1'、'B2'的行列信息,其中字母是列信息,数字是行号

# 2)以行为单位获取单元格对象
# 工作表.iter_rows(最小行号, 最大行号, 最小列号, 最大列号)
cells = sheet.iter_rows(1, 4, 1, 4)
print(list(cells))

row_4 = sheet.iter_rows(4, 4)
print(list(row_4))

cells = sheet.iter_rows(2, 4, 1, 2)
print(list(cells))

# 3)以列为单位获取单元格对象
cells = sheet.iter_cols(1, 4, 1, 4)
print(list(cells))

all_scores = sheet.iter_cols(4, 4, 2, 4)
# print(list(all_scores))
for score_cell in next(all_scores):
    print(score_cell.value)

二、selenium部分选项设置

from selenium import webdriver
# from selenium.webdriver import ChromeOptions

url = 'https://www.jd.com'

# 1.创建设置选项
options = webdriver.ChromeOptions()

# 2.添加选项参数
# 1) 取消测试环境
options.add_experimental_option('excludeSwitches', ['enable-automation'])

# 2) 取消图片加载(提高爬虫效率)
options.add_experimental_option("prefs", {"profile.managed_default_content_settings.images": 2})

b = webdriver.Chrome(options=options)
b.get(url)
print(b.page_source)

三、frame的使用

from selenium import webdriver

url = 'https://mail.163.com/'

b = webdriver.Chrome()
b.get(url)

"""
有的时候会遇到这样的网页:一个网页对应的html标签嵌套了其他的html标签
(前端如果要实现嵌套的功能必须要将被嵌套的html放在iframe标签中),
如果需要爬取网页内容在嵌套的html里面,需要先让浏览器选中内容嵌套的html。
(浏览器对象默认选中的是最外面的html标签)
"""
# 1. 获取提供html标签的iframe标签
box = b.find_element_by_css_selector('#loginDiv>iframe')

# 2.切换frame
b.switch_to.frame(box)

print(b.page_source)

四、多线程的基础知识

# 一个进程默认有一个线程,这个线程叫主线程。其他的线程(需要手动创建)都叫子线程
# 如果一个python程序需要子线程需要手动创建线程类Thread的对象

import time
from datetime import datetime
from threading import Thread
# Thread类 - 线程类   Thread类对象 - 子线程


def download(name):
    print(f'{name}开始下载:{datetime.now()}')
    time.sleep(2)
    print(f'{name}下载结束:{datetime.now()}')


# 在一个线程(主线程)中下载三个电影需要6s
# download('肖申克的救赎')
# download('霸王别姬')
# download('阿甘正传')

# 1)创建线程
t1 = Thread(target=download, args=('肖申克的救赎',))
t2 = Thread(target=download, args=('霸王别姬',))
t3 = Thread(target=download, args=('阿甘正传',))

# 2)启动线程
t1.start()
t2.start()
t3.start()

五、练习

1.网易邮箱的爬取(body嵌套)

from selenium import webdriver
from selenium.webdriver import ChromeOptions

options = ChromeOptions()
options.add_experimental_option('excludeSwitches', ['enable-automation'])
b = webdriver.Chrome(options=options)

b.get('https://mail.163.com/')
# 需要爬取的内容在嵌套页面中(嵌套页面在iframe标签中),获取标签前需要切换页面
# 1.拿到嵌套页面对应的iframe标签
frame = b.find_element_by_css_selector('#loginDiv>iframe')
# 2.切换页面
b.switch_to.frame(frame)
# 3.获取嵌套页面中标签
user_name = b.find_element_by_name('email')
password = b.find_element_by_name('password')
login_btn = b.find_element_by_id('dologin')
user_name.send_keys('y_t209')
password.send_keys('123456')
login_btn.click()

2.51job网页爬取

import requests
from re import findall
from json import loads
import time
import os
import openpyxl


headers = {
    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36'
}


def get_one_page(page):
    url = f'https://search.51job.com/list/000000,000000,0000,00,9,99,数据分析,2,{page}.html?lang=c&postchannel=0000&workyear=99&cotype=99°reefrom=99&jobterm=99&companysize=99&ord_field=0&dibiaoid=0&line=&welfare='
    response = requests.get(url, headers=headers)
    if response.status_code == 200:
        json_data = findall(r'window.__SEARCH_RESULT__\s*=\s*(\{.+?\})</script>', response.text)[0]
        return loads(json_data)['engine_search_result']
    else:
        print('请求失败!')


def get_all_data():
    all_data = []
    page = 1
    while True:
        result = get_one_page(page)
        if not result:
            print('没有更多数据')
            break

        page += 1
        # all_data.extend(result)
        # yield result
        # 保存到excel文件中
        save_page_data(result)

        print(f'获取第{page}页数据成功!')
        time.sleep(1)

    # return all_data


def get_work_book():
    # 1. 判断文件是否存在, 存在就加载,不存在就创建
    if os.path.exists('files/招聘信息.xlsx'):
        wb = openpyxl.load_workbook('files/招聘信息.xlsx')
    else:
        wb = openpyxl.Workbook()

    # 2. 判断是否存在数据分析的表
    names = wb.sheetnames
    if '数据分析' in names:
        sheet = wb['数据分析']
    else:
        sheet = wb.create_sheet('数据分析')
        titles = ['岗位名称', '薪资', '公司名称', '公司性质', '公司地址', '要求', '福利']
        for col in range(1, len(titles) + 1):
            sheet.cell(1, col).value = titles[col - 1]

    return wb, sheet


def save_page_data(data: list):
    row = sheet.max_row + 1
    for job in data:
        # 写入对应的数据
        # titles = ['岗位名称', '薪资', '公司名称', '公司性质', '公司地址', '要求', '福利']
        job_info = [
            job.get('job_name', ''),
            job.get('providesalary_text', ''),
            job.get('company_name', ''),
            job.get('companytype_text', ''),
            job.get('workarea_text', ''),
            '/'.join(job.get('attribute_text', ['-', '-', '-', '-', '-'])),
            job.get('jobwelf', '')
        ]
        for col in range(1, len(job_info)+1):
            sheet.cell(row, col).value = job_info[col-1]

        print(job)
        row += 1
    wb.save('files/招聘信息.xlsx')


if __name__ == '__main__':
    wb, sheet = get_work_book()
    get_all_data()

3.51job切换城市

from selenium import webdriver
from selenium.webdriver.common.keys import Keys

url = 'https://www.51job.com/'
b = webdriver.Chrome()

b.get(url)

input = b.find_element_by_css_selector('#kwdselectid')
input.send_keys('数据分析')
input.send_keys(Keys.ENTER)

allcity = b.find_element_by_css_selector('.allcity')
allcity.click()

print(b.page_source)

beijing = b.find_element_by_css_selector('.panel_lnp.panel_py.panel_ct2 .de.d3 tbody tr td em')
print(beijing.text)
beijing.click()

sure = b.find_element_by_css_selector('#popop > div > div.but_box > span')
sure.click()