您现在的位置是:首页 >技术教程 >十一周内容笔记网站首页技术教程
十一周内容笔记
十一周内容笔记
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)
问如何叫醒一个装睡的人?