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


产生随机时间并随机模拟浏览器用于访问网页,降低被服务器识别出是爬虫而被禁的可能 。
4.获取领导的fid
def get_fid():'''获取所有领导id'''with open('url_fid.txt', 'r') as f:content = f.read()fids = content.split()return fids
每个领导都有一个fid用于区分,这里采用手动获取fid并保存到txt中,在开始爬取时再逐行读取 。
5.获取领导所有留言链接
def get_detail_urls(position, list_url):'''获取每个领导的所有留言链接'''user_agent = get_user_agent()chrome_options.add_argument('user-agent=%s' % user_agent)drivertemp = webdriver.Chrome(options=chrome_options)drivertemp.maximize_window()drivertemp.get(list_url)time.sleep(2)# 循环加载页面try:while WebDriverWait(drivertemp, 50, 2).until(EC.element_to_be_clickable((By.ID, "show_more"))):datestr = WebDriverWait(drivertemp, 10).until(lambda driver: driver.find_element_by_xpath('//*[@id="list_content"]/li[position()=last()]/h3/span')).text.strip()datestr = re.search(r'\d{4}-\d{2}-\d{2}', datestr).group()date = dparser.parse(datestr, fuzzy=True)print('正在爬取链接 --', position, '--', date)if date < start_date:break# 模拟点击加载drivertemp.find_element_by_xpath('//*[@id="show_more"]').click()time.sleep(get_time())detail_elements = drivertemp.find_elements_by_xpath('//*[@id="list_content"]/li/h2/b/a')# 获取所有链接for element in detail_elements:detail_url = element.get_attribute('href')yield detail_urldrivertemp.quit()except TimeoutException:drivertemp.quit()get_detail_urls(position, list_url)
【三Python 爬取留言板留言:多进程版+selenium模拟】根据第4步提供的fid找到一个领导对应的所有留言的链接,由于领导的留言列表并未一次显示完,下方有一个加载更多按钮,如下

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

文章插图
每次需要进行点击向下加载,所以要模拟点击的操作,向下滑动,等完全加载后再次点击,直到底部,有可能会滑倒页面最底部不再显示按钮或者由于被反爬或网络不好而未加载出来,此时定位元素会超时,增加异常处理,递归调用 。
函数返回值时,不是一次返回一个列表,而是通过yield关键字生成生成器,按照程序执行的进度生成url,可以减少内存的压力 。
6.获取留言详情
def get_message_detail(driver, detail_url, writer, position):'''获取留言详情'''print('正在爬取留言 --', position, '--', detail_url)driver.get(detail_url)# 判断,如果没有评论则跳过try:satis_degree = WebDriverWait(driver, 2.5).until(lambda driver: driver.find_element_by_class_name("sec-score_firstspan")).text.strip()except:return# 获取留言各部分内容message_date_temp = WebDriverWait(driver, 2.5).until(lambda driver: driver.find_element_by_xpath("/html/body/div[6]/h3/span")).textmessage_date = re.search(r'\d{4}-\d{2}-\d{2}', message_date_temp).group()message_datetime = dparser.parse(message_date, fuzzy=True)if message_datetime < start_date:returnmessage_title = WebDriverWait(driver, 2.5).until(lambda driver: driver.find_element_by_class_name("context-title-text")).text.strip()label_elements = WebDriverWait(driver, 2.5).until(lambda driver: driver.find_elements_by_class_name("domainType"))try:label1 = label_elements[0].text.strip()label2 = label_elements[1].text.strip()except:label1 = ''label2 = label_elements[0].text.strip()message_content = WebDriverWait(driver, 2.5).until(lambda driver: driver.find_element_by_xpath("/html/body/div[6]/p")).text.strip()replier = WebDriverWait(driver, 2.5).until(lambda driver: driver.find_element_by_xpath("/html/body/div[8]/ul/li[1]/h3[1]/i")).text.strip()reply_content = WebDriverWait(driver, 2.5).until(lambda driver: driver.find_element_by_xpath("/html/body/div[8]/ul/li[1]/p")).text.strip()reply_date_temp = WebDriverWait(driver, 2.5).until(lambda driver: driver.find_element_by_xpath("/html/body/div[8]/ul/li[1]/h3[2]/em")).textreply_date = re.search(r'\d{4}-\d{2}-\d{2}', reply_date_temp).group()review_scores = WebDriverWait(driver, 2.5).until(lambda driver: driver.find_elements_by_xpath("/html/body/div[8]/ul/li[2]/h4[1]/span/span/span"))resolve_degree = review_scores[0].text.strip()[:-1]handle_atti = review_scores[1].text.strip()[:-1]handle_speed = review_scores[2].text.strip()[:-1]review_content = WebDriverWait(driver, 2.5).until(lambda driver: driver.find_element_by_xpath("/html/body/div[8]/ul/li[2]/p")).text.strip()is_auto_review = '是' if (('自动默认好评' in review_content) or ('默认评价' in review_content)) else '否'review_date_temp = WebDriverWait(driver, 2.5).until(lambda driver: driver.find_element_by_xpath("/html/body/div[8]/ul/li[2]/h4[2]/em")).textreview_date = re.search(r'\d{4}-\d{2}-\d{2}', review_date_temp).group()# 存入CSV文件writer.writerow([position, message_title, label1, label2, message_date, message_content, replier, reply_content, reply_date,satis_degree, resolve_degree, handle_atti, handle_speed, is_auto_review, review_content, review_date])