三 Python 爬取留言板留言:多进程版+selenium模拟( 三 )


我们只需要有评论的留言,因此在最开始要过滤掉没有评论的留言 。然后通过xpath、等方式定位到相应的元素获取留言的各个部分的内容,每条留言共保存14个属性,并保存到csv中 。
7.获取并保存领导所有留言
def get_officer_messages(index, fid):'''获取并保存领导的所有留言'''user_agent = get_user_agent()chrome_options.add_argument('user-agent=%s' % user_agent)driver = webdriver.Chrome(options=chrome_options)list_url = "http://liuyan.people.com.cn/threads/list?fid={}#state=4".format(fid)driver.get(list_url)try:position = WebDriverWait(driver, 10).until(lambda driver: driver.find_element_by_xpath("/html/body/div[4]/i")).textprint(index, '-- 正在爬取 --', position)start_time = time.time()csv_name = position + '.csv'# 文件存在则删除重新创建if os.path.exists(csv_name):os.remove(csv_name)with open(csv_name, 'a+', newline='', encoding='gb18030') as f:writer = csv.writer(f, dialect="excel")writer.writerow(['职位姓名', '留言标题', '留言标签1', '留言标签2', '留言日期', '留言内容', '回复人', '回复内容', '回复日期', '满意程度', '解决程度分', '办理态度分','办理速度分', '是否自动好评', '评价内容', '评价日期'])for detail_url in get_detail_urls(position, list_url):get_message_detail(driver, detail_url, writer, position)time.sleep(get_time())end_time = time.time()crawl_time = int(end_time - start_time)crawl_minute = crawl_time // 60crawl_second = crawl_time % 60print(position, '已爬取结束!!!')print('该领导用时:{}分钟{}秒 。'.format(crawl_minute, crawl_second))driver.quit()time.sleep(5)except:driver.quit()get_officer_messages(index, fid)
获取该领导的职位信息并为该领导创建一个独立的csv用于保存提取到的留言信息,增加异常处理递归调用,调用()方法获取每条留言的具体信息并保存,计算出每个领导的执行时间 。
8.合并文件
def merge_csv():'''将所有文件合并'''file_list = os.listdir('.')csv_list = []for file in file_list:if file.endswith('.csv'):csv_list.append(file)# 文件存在则删除重新创建if os.path.exists('DATA.csv'):os.remove('DATA.csv')with open('DATA.csv', 'a+', newline='', encoding='gb18030') as f:writer = csv.writer(f, dialect="excel")writer.writerow(['职位姓名', '留言标题', '留言标签1', '留言标签2', '留言日期', '留言内容', '回复人', '回复内容', '回复日期', '满意程度', '解决程度分', '办理态度分','办理速度分', '是否自动好评', '评价内容', '评价日期'])for csv_file in csv_list:with open(csv_file, 'r', encoding='gb18030') as csv_f:reader = csv.reader(csv_f)line_count = 0for line in reader:line_count += 1if line_count != 1:writer.writerow((line[0], line[1], line[2], line[3], line[4], line[5], line[6], line[7], line[8],line[9], line[10], line[11], line[12], line[13], line[14], line[15]))
将爬取的所有领导的数据进行合并 。
9.主函数调用
多线程的实现主要在这部分,有2种方式实现:
def main():'''主函数'''fids = get_fid()print('爬虫程序开始执行:')s_time = time.time()# 创建进程池pool = Pool(3)# 将任务加入进程池并传入参数for index, fid in zip(range(1, len(fids) + 1), fids):pool.apply_async(get_officer_messages, (index, fid))pool.close()pool.join()print('爬虫程序执行结束!!!')print('开始合成文件:')merge_csv()print('文件合成结束!!!')e_time = time.time()c_time = int(e_time - s_time)c_minute = c_time // 60c_second = c_time % 60print('{}位领导共计用时:{}分钟{}秒 。'.format(len(fids), c_minute, c_second))if __name__ == '__main__':'''执行主函数'''main()