嗨喽,大家好呀~这里是爱看美女的茜茜呐
又到了学Python时刻~
在我们爬取数据的时候,有时候它运行速度会非常慢
那么怎么解决呢?
这里给大家带来一个多线程的方法
我们用采集二手车来举例
Python 3.8
Pycharm
requests 数据请求模块
parsel 数据解析模块
re
csv 内置模块
发送请求, 模拟浏览器对于url地址发送请求
获取数据, 获取服务器返回响应数据
开发者工具: response
解析数据, 提取我们想要的数据内容
提取: 房源基本信息
保存数据, 把数据保存表格文件里面
多页数据采集
导入模块
# 导入数据请求模块 --> 第三方模块 需要安装 pip install requests
import requests
# 导入数据解析模块 --> 第三方模块 需要安装 pip install parsel
import parsel
# 导入csv
import csv
# 导入时间模块
import time
( 源码\解答\资料\教程点击此处跳转跳转文末名片加入,找管理员小姐姐领取呀~)
time_1 = time.time()
创建文件 <对象>
f = open('data.csv', mode='a', encoding='utf-8', newline='')
csv_writer = csv.DictWriter(f, fieldnames=['标题''小区','总价','单价','户型','面积','朝向','装修','楼层','建筑日期','建筑类型','详情页',
])
写入表头
csv_writer.writeheader()
“”"
伪装模拟: 请求头 字典数据类型 构建完整键值对
headers 可以直接在开发者工具里面进行复制
200 状态码 表示请求成功
“”"
for page in range(1, 101):try:print(f'==================正在采集第{page}页的数据内容==================')
请求链接
( 因不可抗原因,不能出现网址,会发不出去,用图片代替了,大家照着敲一下
或者点击此处跳转跳转文末名片加入裙聊,找管理员小姐姐领取呀~ )
模拟伪装
headers = {# User-Agent 用户代理, 表示浏览器基本身份信息'User-Agent': ' Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36'}
发送请求
response = requests.get(url, headers)
“”"
获取数据, 获取服务器返回响应数据
开发者工具: response
获取网页源代码
response.text 获取响应文本数据, 字符串数据类型 获取html字符串数据内容
response.json() 获取响应字典数据 json数据 必须是完整json数据格式
解析数据, 提取我们想要的数据内容
提取: 房源基本信息
解析方法:
xpath
re正则
css
json数据处理
css选择器: 根据标签属性提取数据内容
“”"
html_data = requests.get(link).textselect = parsel.Selector(html_data)
把获取下来 html字符串数据 response.text , 转成可解析对象
selector = parsel.Selector(response.text)
第一次提取, 把包含房源数据信息 标签全部获取下来 获取所有li标签
lis = selector.css('sellListContent li')
for循环把列表里 元素一个一个提取出来
for li in lis:
源码、解答、资源、学习交流可加企鹅裙:261823976##title = li.css('.title a::text').get() # 标题href = li.css('.title a::attr(href)').get() # 详情页totalPrice = li.css('.totalPrice span::text').get() # 售价unitPrice = li.css('.unitPrice span::text').get() # 单价string = select.css('.comments div:nth-child(7) .comment_text::text').get()
join把列表合并字符串
area = '-'.join(li.css('.info .flood .positionInfo a::text').getall()) # 小区houseInfo = li.css('.info .address .houseInfo::text').get()
split 把字符串分割成列表
houseType = houseInfo.split(' | ')[0] # 户型houseArea = houseInfo.split(' | ')[1] # 面积orientation = houseInfo.split(' | ')[2] # 朝向renovation = houseInfo.split(' | ')[3] # 装修floor = houseInfo.split(' | ')[4] # 楼层
判断 houseInfo.split(’ | ') 有多少个元素, 如果6个元素 说明没有建造日期
if len(houseInfo.split(' | ')) == 6:date = ''else:date = houseInfo.split(' | ')[5]buildingType = houseInfo.split(' | ')[-1] # 建筑类型dit = {'标题': title,'小区': area,'总价': totalPrice,'单价': unitPrice,'户型': houseType,'面积': houseArea,'朝向': orientation,'装修': renovation,'楼层': floor,源码、解答、资源、学习交流可加企鹅裙:261823976##'建筑日期': date,'建筑类型': buildingType,'详情页': href,}csv_writer.writerow(dit)print(string)except:print('报名系统课程可以添加清风老师微信: pythonmiss')
mport requests
import parsel
import re
import csv
# 线程池模块
import concurrent.futures
import timedef get_response(html_url):"""发送请求函数:param html_url::return:"""headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36'}response = requests.get(url=html_url, headers=headers)return responsedef get_content(html_url):"""获取数据函数:param html_url::return:"""response = get_response(html_url)html_data = get_response(link).textselector = parsel.Selector(response.text)select = parsel.Selector(html_data)lis = selector.css('.sellListContent li')content_list = []for li in lis:title = li.css('.title a::text').get() # 标题area = '-'.join(li.css('.positionInfo a::text').getall()) # 小区Price = li.css('.totalPrice span::text').get() # 总价Price_1 = li.css('.unitPrice span::text').get().replace('元/平', '') # 单价houseInfo = li.css('.houseInfo::text').get() # 信息HouseType = houseInfo.split(' | ')[0] # 户型HouseArea = houseInfo.split(' | ')[1].replace('平米', '') # 面积direction = houseInfo.split(' | ')[2].replace(' ', '') # 朝向renovation = houseInfo.split(' | ')[3] # 装修floor_info = houseInfo.split(' | ')[4]floor = floor_info[:3] # 楼层floor_num = re.findall('(\d+)层', floor_info)[0] # 层数BuildingType = houseInfo.split(' | ')[-1]string = select.css('.comments div:nth-child(7) .comment_text::text').get()href = li.css('.title a::attr(href)').get() # 详情页if len(houseInfo.split(' | ')) == 6:date = 'None'else:date = houseInfo.split(' | ')[5].replace('年建', '') # 日期print(string)dit = {源码、解答、资源、学习交流可加企鹅裙:261823976##'标题': title,'内容': string,'小区': area,'总价': Price,'单价': Price_1,'户型': HouseType,'面积': HouseArea,'朝向': direction,'装修': renovation,'楼层': floor,'层数': floor_num,'建筑日期': date,'建筑类型': BuildingType,'详情页': href,}content_list.append(dit)return content_listdef main(page):"""主函数:param page::return:"""print(f'===============正在采集第{page}页的数据内容===============')
content_list = get_content(html_url=url)for content in content_list:csv_writer.writerow(content)if __name__ == '__main__':time_1 = time.time()link = 'http:// *******.com/article/149'# 创建文件f = open('data多线程.csv', mode='a', encoding='utf-8', newline='')csv_writer = csv.DictWriter(f, fieldnames=['标题','内容','小区','总价','单价','户型','面积','朝向','装修','楼层','层数','建筑日期','建筑类型','详情页',])csv_writer.writeheader()# 线程池执行器 max_workers 最大线程数exe = concurrent.futures.ThreadPoolExecutor(max_workers=10)for page in range(1, 11):exe.submit(main, page)exe.shutdown()time_2 = time.time()use_time = int(time_2 - time_1)# 总计耗时: 9print('总计耗时:', use_time)
感谢你观看我的文章呐~本次航班到这里就结束啦 🛬
希望本篇文章有对你带来帮助 🎉,有学习到一点知识~
躲起来的星星🍥也在努力发光,你也要努力加油(让我们一起努力叭)。
最后,宣传一下呀~👇👇👇更多源码、资料、素材、解答、交流皆点击下方名片获取呀👇👇👇