Python的os模块、selenium环境搭建、selenium简单爬虫

本文介绍了使用Python进行链家二手房信息的爬取,包括通过BeautifulSoup和XPath解析页面,按行政区划分数据,以及使用os模块进行文件操作。同时,文章涉及了selenium模块的使用,如设置浏览器对象、控制页面滚动和处理动态加载内容,以及selenium的显式和隐式等待策略。
摘要由CSDN通过智能技术生成

十一周内容笔记

day31

01-链家二手房爬虫大作业初版(没有带包括写入操作,单纯的爬)

1.使用bs4或者xpath。

2.爬虫功能使用函数封装(一个功能对应一个函数)。

3.此作业有可能会成为毕设的一部分功能。

4.成都链家二手房信息爬取。

5.按照锦江、青羊等行政区级别爬取数据。

6.想办法判断每个行政区的二手房页数。

7.引入一些修饰性的内容(进度条等)。

8.最好是一个csv文件只保存一个行政区的内容(一个文件中数据越多,写入速度越慢)。

真吓人

import requests
import requests_cache
from lxml import etree
import json
from tqdm import tqdm


def requests_get(link):
    """负责获取网页源代码的函数"""
    # 使用requests_cache模块保存缓存
    requests_cache.install_cache(cache_name='lianjia_cd')
    Headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36 Edg/112.0.1722.39'
    }
    response = requests.get(url=link, headers=Headers)
    return response.text if response.status_code == 200 else response.status_code


def region(source):
    """获取行政区及对应链接"""
    root = etree.HTML(source)
    a_list = root.xpath('./body/div[3]/div[@class="m-filter"]/div[@class="position"]/dl[2]/dd/div[1]/div/a')
    region_info = {i.xpath('./text()')[0]: 'https://cd.lianjia.com' + i.xpath('./@href')[0] for i in a_list}
    return region_info


def get_page_num(region_info):
    """获取每个行政区的页数"""
    num_dict = {}
    for key, href in region_info.items():
        # 再次调用requests_get函数
        html_source = requests_get(href)
        root = etree.HTML(html_source)
        page_info = root.xpath('./body/div[4]/div[1]/div[@class="contentBottom clear"]/div[2]/div/@page-data')
        page_num = json.loads(page_info[0])['totalPage']
        num_dict.setdefault(key, page_num)
    return num_dict


def house_info(region_link, region_page):
    """获取二手房信息"""
    for key, link in region_link.items():
        total_num = region_page[key]
        for page in tqdm(range(1, total_num + 1), desc=f'链家成都{key}二手房爬虫进度'):
            href = link + f'pg{page}/'
            # 调用requests_get函数,开始信息爬取
            html_source = requests_get(href)
            root = etree.HTML(html_source)
            li_list = root.xpath('./body/div[4]/div[1]/ul/li')
            for i in li_list:
                # 房屋标题
                house_title = i.xpath('./div[1]/div[1]/a/text()')[0]
                # 房屋详情页标签
                house_link = i.xpath('./div[1]/div[1]/a/@href')[0]


def main(link):
    # 1.调用requests_get函数,进行链家首页请求
    html_sourse = requests_get(link)
    # 2.调用region函数,获取行政区及链接
    region_dict = region(html_sourse)
    # 3.获取每个行政区的页数
    page_number = get_page_num(region_dict)
    # 4.调用house_info函数,获取二手房信息
    house_info(region_dict, page_number)


if __name__ == '__main__':
    URL = 'https://cd.lianjia.com/ershoufang/rs'
    main(URL)

day32

01-os系列模块

os模块:os模块实现了一些计算机的命令

1.os.listdir():查看指定路径下的所有文件和文件夹

import os
print(os.listdir(path='./'))
# 返回:['01-os系列模块.py']

2.os.path.exists():存在性判断,判断是否存在指定的文件或文件夹,存在返回True,不存在返回False

# if not os.path.exists('./数据'):
# os.path.isdir():判断某个文件夹是否存在,存在返回True,反之返回False
if not os.path.isdir('./数据'):
    # os.mkdir():创建文件夹
    os.mkdir('./数据')
else:
    # os.rmdir(path):根据path移除文件夹
    os.rmdir(path='./')

# 判断某个文件是否存在
if os.path.isfile('./数据/test.txt'):
    # os.remove():根据path移除文件
    os.remove('./数据/test.txt')

# 循环在数据文件夹下,创建名字为1-100的文件夹
for i in range(1, 101):
    if not os.path.isdir(f'./数据/{i}'):
        os.mkdir(f'./数据/{i}')

3.改名操作

# os.rename():将指定的文件夹或目录按照指定的路径和名字进行重命名和移动
for i in os.listdir('./数据'):
    os.rename(f'./数据/{i}', f'./数据/x{i}')

02-链家二手房爬虫大作业写入操作补充

对house_info方法进行了重写,并加入了data_write方法,用house_info函数嵌套实现获取信息和写入的操作

def house_info(region_link, region_page):
    """获取二手房信息"""

    def page_info(key_1, link_1, total_num_1):
        for page in tqdm(range(1, total_num_1 + 1), desc=f'链家成都{key_1}二手房爬虫进度'):
            href = link_1 + f'pg{page}/'
            # 调用requests_get函数,开始信息爬取
            html_source = requests_get(href)
            root = etree.HTML(html_source)
            li_list = root.xpath('./body/div[4]/div[1]/ul/li')
            for i in li_list:
                # 房屋标题
                house_title = i.xpath('./div[1]/div[1]/a/text()')[0]
                # 房屋详情页标签
                house_link = i.xpath('./div[1]/div[1]/a/@href')[0]
                yield [key_1, house_title, house_link]

    for key, link in region_link.items():
        total_num = region_page[key]
        yield_data = page_info(key, link, total_num)
        # 调用data_write函数
        data_write(key, yield_data)

def data_write(region, data):
    """将数据写入文件"""
    path = '链家数据'
    if not os.path.isdir(path):
        os.mkdir(path)
    with open(f'./{path}/成都链家{region}二手房.csv', 'w', encoding='utf-8', newline='') as file:
        csv.writer(file).writerow(['房屋标题', '房屋详情页链接'])
        for i in data:
            csv.writer(file).writerow(i)

03-selenium环境搭建

selenium用来解决的是动态页面的问题

1.使用谷歌浏览器(Google Chrome)

2.安装selenium模块:pip install selenium

3.下载、配置谷歌浏览器驱动文件
https://registry.npmmirror.com/binary.html?path=chromedriver/
从此链接寻找与已安装的chrome版本号相同或者小于此版本号的最接近的版本

4.验证环境是否能用

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
# 使用webdriver包中的chrome方法创建谷歌浏览器对象
browser = webdriver.Chrome(service=Service(executable_path='./chromedriver.exe'))

day33

01-selenium简单操作

一、什么是selenium?
selenium是一个用于web应用程序测试的工具。selenium运行于浏览器中,能够像真正的用户一样操作浏览器,支持的浏览器IE(7、8、9、10、11)、Google Chrome、Mac Safari、Edge、Opera、FireFox,
selenium主要在爬虫中解决JavaScript渲染问题。

二、创建浏览器对象

1.导入浏览器驱动模块

from selenium import webdriver
# 我们现在安装的是selenium4.x版本,4.x版本要求浏览器驱动使用服务方法导入
from selenium.webdriver.chrome.service import Service
import time

s = Service(executable_path='../day32/chromedriver.exe')
browser = webdriver.Chrome(service=s)

2.控制浏览器窗口的大小

# maximize_window():窗口最大化
browser.maximize_window()
# set_window_size:自定义尺寸
browser.set_window_size(400, 400)

3.请求连接

link1 = 'https://www.baidu.com/'
browser.get(url=link1)
time.sleep(2)

link2 = 'https://www.jd.com/'
browser.get(url=link2)
time.sleep(2)

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

4.控制页面的前进后退

# back:后退
browser.back()
time.sleep(2)
# forward:前进
browser.forward()

5.新建、切换选项卡

# window_handles:查看目前有几个选项卡
# print(browser.window_handles)
# execute_script():能够执行javascript的代码
# window.open():新建选项卡
browser.execute_script('window.open()')
# print(browser.window_handles)
# switch_to:切换
browser.switch_to.window(browser.window_handles[-1])
browser.get(url='https://www.baidu.com/')
# close():关闭当前选项卡
# close用在需要访问大量页面时,通过关闭没用的页面,减少内存消耗
browser.close()

6.quit():退出浏览器

# 退出浏览器,如果没有quit方法,浏览器窗口虽然被关闭,但是进程还在
# quit方法能够在关闭浏览器窗口时,同时清理缓存和进程。
browser.quit()

02-selenium爬取英雄联盟

# 导入浏览器驱动模块
from selenium import webdriver
# 我们现在安装的是selenium4.x版本,4.x版本要求浏览器驱动使用服务方法导入
from selenium.webdriver.chrome.service import Service
import time

s = Service(executable_path='../day32/chromedriver.exe')
browser = webdriver.Chrome(service=s)

link = 'https://101.qq.com/#/hero'
browser.get(url=link)
# 休眠:多花点时间等页面加载完再打印网页源码
time.sleep(2)

# 网页源代码:字符串类型
html_source = browser.page_source
# print(html_source)

# 方式一:拿到字符串类型网页源码,可以通过bs4(css选择器)、lxml(xpath)两种方式爬取页面内容。
# 方式二:直接使用selenium效率不算很高的方法爬取页面内容
# find_element:获取定位方式指定的第一个元素(类似于bs4模块的select_one)
# find_elements:获取定位方式指定的全部元素(类似于bs4模块的select)
# text:获取标签内容(类似于bs4模块的text)
# get_attribute():获取标签内属性值(类似于bs4模块的attrs)

# find_element(定位方式, 定位的语法)
# 导入定位方式模块
from selenium.webdriver.common.by import By
li = browser.find_elements(By.CSS_SELECTOR, '#app > div > div.app-main > div > div.app-main-container.infomation-overview > ul > li')
for i in li:
    name = i.find_element(By.XPATH, './div[1]/p').text
    link = i.find_element(By.XPATH, './div[1]/div[1]/img').get_attribute('src')
    print(name, link)

03-selenium爬取京东

越来越有意思了

# 导入浏览器驱动模块
import time

from selenium import webdriver
# 我们现在安装的是selenium4.x版本,4.x版本要求浏览器驱动使用服务方法导入
from selenium.webdriver.chrome.service import Service
# 导入定位方式包
from selenium.webdriver.common.by import By
# 导入键盘事件包
from selenium.webdriver.common.keys import Keys

# 创建浏览器配置对象
options = webdriver.ChromeOptions()
# 不加载图片,提升速度
options.add_argument('blink-settings=imagesEnabled=false')

s = Service(executable_path='../day32/chromedriver.exe')
# 将配置添加到浏览器对象中
browser = webdriver.Chrome(service=s, options=options)

link = 'https://www.jd.com/?cu=true&utm_source=baidu-search&utm_medium=cpc&utm_campaign=t_262767352_baidusearch&utm_term=304792146438_0_eb6484ee604444e38bd22aad414d55cc'
browser.get(url=link)
# 寻找搜索框,输入商品名,回车或点击搜索按钮
input_field = browser.find_element(By.CSS_SELECTOR, '#key')
# send_keys:向输入框传入内容
input_field.send_keys('电脑')
# # 敲回车
# input_field.send_keys(Keys.ENTER)
# 寻找搜索按钮,点击
# 点击事件:click()
browser.find_element(By.CSS_SELECTOR, '#search > div > div.form > button').click()
while True:
    # 为什么每一页的信息没有获取全?
    # JavaScript的瀑布式加载
    # 如何解决瀑布式加载?selenium自动滚动页面
    y = 0
    max_y = 10000
    while y < max_y:
        # java_script进行页面滚动:window.scrollTo(x, y)
        browser.execute_script(f'window.scrollTo(0, {y})')
        y += 500
        time.sleep(1)
    # 为什么在此处休眠?动态网站受网速影响要等加载完才有能执行操作,要不然就没数据
    time.sleep(5)
    # 爬取电脑相关信息
    # 先找到每一页所有电脑所在标签
    li_list = browser.find_elements(By.XPATH, '//*[@id="J_goodsList"]/ul/li')
    # print(li_list)
    for i in li_list[1:]:
        pc_title = i.find_element(By.XPATH, './div[1]/div[3]/a/em').text
        pc_price = i.find_element(By.XPATH, './div[1]/div[2]/strong/i').text
        print(pc_title, pc_price)

    # 翻页操作
    # 问题:为什么动态页面不能直接改链接?有时候页面变化了不一定链接也会变化,只能用selenium来实现点击翻页的动作
    # 1.先找下一页的a标签
    a_button = browser.find_element(By.XPATH, '//*[@id="J_bottomPage"]/span[1]/a[last()]')
    # 2.如果a标签内的属性为pn-next,才能点击
    if a_button.get_attribute('class') == 'pn-next':
        a_button.click()
    else:
        break

04-selenium的显式等待和隐式等待

sleep性能太差了,所以并不适合用于selenium。

selenium有自己的等待策略:

隐式等待:全局(在创建完浏览器对象以后设置)设定一次,即可全局控制等待,并且只要等待内容被抓取到,直接结束等待。(粗略的等待)

显式等待:非全局等待,可以给某段内容单独设定,随意指定等待什么出现。(更精确的等待)

区别:隐式等待写起来更加的方便,显式等待写起来特别麻烦。

承接前面京东的爬虫进行说明

# 导入浏览器驱动模块

from selenium import webdriver
# 我们现在安装的是selenium4.x版本,4.x版本要求浏览器驱动使用服务方法导入
from selenium.webdriver.chrome.service import Service
# 导入定位方式包
from selenium.webdriver.common.by import By
# 导入显式等待的包
from selenium.webdriver.support.wait import WebDriverWait
# 导入”期望“包
from selenium.webdriver.support import expected_conditions as EC


# 创建浏览器配置对象
options = webdriver.ChromeOptions()
# 不加载图片,提升速度
options.add_argument('blink-settings=imagesEnabled=false')

s = Service(executable_path='../day32/chromedriver.exe')
# 将配置添加到浏览器对象中
browser = webdriver.Chrome(service=s, options=options)
# 创建完浏览器对象以后,全局设定一次隐式等待:implicitly_wait()
# time_to_wait=100:最大等待100秒
browser.implicitly_wait(time_to_wait=100)


link = 'https://www.jd.com/?cu=true&utm_source=baidu-search&utm_medium=cpc&utm_campaign=t_262767352_baidusearch&utm_term=304792146438_0_eb6484ee604444e38bd22aad414d55cc'
browser.get(url=link)
# 寻找搜索框,输入商品名,回车或点击搜索按钮
input_field = browser.find_element(By.CSS_SELECTOR, '#key')
# send_keys:向输入框传入内容
input_field.send_keys('电脑')
# # 敲回车
# input_field.send_keys(Keys.ENTER)
# 寻找搜索按钮,点击
# 点击事件:click()
browser.find_element(By.CSS_SELECTOR, '#search > div > div.form > button').click()
# 设置显示等待的条件
# WebDriverWait(browser, timeout=10):显示等待检测的browser浏览器对象,10秒后超时
# until(条件):直到......才......
# 条件设置:需要使用期望
# 此处检查”品牌:”这3个符号是否出现在了xpath路径表达式的指定位置
flag = EC.text_to_be_present_in_element(
    (By.XPATH, '//*[@id="J_selector"]/div[1]/div/div[1]/strong'),
    '品牌:'
)
WebDriverWait(browser, timeout=10).until(flag)
# 显式等待:可以用于检测网页中指定的用户名是否登陆成功等。


pc_title = browser.find_element(By.XPATH, '//*[@id="J_goodsList"]/ul/li[2]/div[1]/div[3]/a/em').text
print(pc_title)

问如何叫醒一个装睡的人?

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老树盘根_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值