发布时间:2019-02-23 15:02:11编辑:Run阅读(5119)
分析目标网站:https://www.cnblogs.com/
爬取的内容是编程语言里面的python技术文章
它这里是有js动态加载的标签,而且经过观察()里面的数字是会随机变化的,并不是写死的(推测是一种防爬虫策略)。
如何解决呢?
直接获取标签的text文本内容,然后在把text内容赋值给xpath(标签选择器),这样不管数字如何变化,得到的都是最新的数字,话不多说,直接上代码:
from selenium import webdriver from selenium.webdriver.common.action_chains import ActionChains import time browser = webdriver.Chrome() http = 'https://www.cnblogs.com/' browser.get(http) browser.implicitly_wait(20) # 找到编程语言标签的content label_content=browser.find_element_by_xpath("//div[@id='cate_title_block']/ul/li[@id='cate_item_2']/a").text print(label_content) # 模拟鼠标悬停加载js,获取下级目录的标签 label_xpath = "//div[@id='cate_title_block']//li/a[text()='{}']".format(label_content) print(label_xpath) ActionChains(browser).move_to_element(browser.find_element_by_xpath(label_xpath)).perform() # 找到python标签的content # 创建一个空的list,把text的值追加进来 list_tmp = [] list_new = [] for i in browser.find_elements_by_xpath("//div[@class='cate_content_block']/ul/li/a"): list_tmp.append(i.text) # 去重和去除''内容 for i in list_tmp: if i not in list_new and i != '': list_new.append(i) print(list_new) # 模拟点击python标签 python_xpath = "//div[@class='cate_content_block']/ul/li/a[text()='{}']".format(list_new[4]) browser.find_element_by_xpath(python_xpath).click() browser.quit()
运行程序效果:
可以看到自动点击到python技术文章那里了,这样写不管编程语言(45)还是python(13), ()里面的数字怎么变,都不会影响程序的运行。
搞定了前面,接下来就是爬取对应文章的title和url了,这里还涉及到数据整合,优化上面的代码,加上日志功能,完整代码如下:
from selenium import webdriver from selenium.webdriver.common.action_chains import ActionChains from mylog import MyLog as mylog import time class GetCnblogs: def __init__(self, url): self.log = mylog() # 实例化mylog类,用于记录日志 self.url = url self.browser = self.setup_browser(self.url) self.simulated_click(self.browser) def setup_browser(self, url): """ 打开目标网站 https://www.cnblogs.com/ :return: browser """ try: # 创建chrome参数对象 browser = webdriver.Chrome() # 利用selenium打开网站 browser.get(url) # 等待网站js代码加载完毕 browser.implicitly_wait(20) except Exception as e: # 记录错误日志 self.log.error('打开目标网站失败:{},错误代码:{}'.format(url, e)) else: # 记录成功日志 self.log.info('打开目标网站成功:{}'.format(url)) # 返回实例化selenium对象 return browser def simulated_click(self, browser): # 找到编程语言标签的content label_content = browser.find_element_by_xpath("//div[@id='cate_title_block']/" "/ul/li[@id='cate_item_2']/a").text # 模拟鼠标悬停加载js,获取下级目录的标签 label_xpath = "//div[@id='cate_title_block']//li/a[text()='{}']".format(label_content) ActionChains(browser).move_to_element(browser.find_element_by_xpath(label_xpath)).perform() # 找到python标签的content, 创建两个空的list list_tmp = [] # 临时的列表,用于保存text内容 list_new = [] # 用于去重和去除''内容 for i in browser.find_elements_by_xpath("//div[@class='cate_content_block']/ul/li/a"): list_tmp.append(i.text) # 去重和去除''内容 for i in list_tmp: if i not in list_new and i != '': list_new.append(i) # 模拟点击python标签 python_xpath = "//div[@class='cate_content_block']/ul/li/a[text()='{}']".format(list_new[4]) browser.find_element_by_xpath(python_xpath).click() # 获取文章title和url地址 title_list = [] url_list = [] title_url_dict = {} for i in browser.find_elements_by_xpath("//div[@class='post_item']/div[@class='post_item_body']/h3/a"): title_list.append(i.text) for i in browser.find_elements_by_xpath("//div[@class='post_item']/div[@class='post_item_body']/h3/a"): url_list.append(i.get_attribute('href')) # 数据合并: title_list标题列表, url_list网站地址列表 i = 1 for x in title_list: title_url_dict.setdefault(i) title_url_dict[i] = {'title': x, 'url': None} i += 1 s = 1 for y in url_list: title_url_dict[s]['url'] = y s += 1 # 记录title,url信息 for i in title_url_dict: self.log.info("\n正在获取第{}篇文章\n标题为:{}\nURL地址:{}/" "".format(i, title_url_dict[i]['title'], title_url_dict[i]['url'])) time.sleep(5) browser.quit() if __name__ == '__main__': url = 'https://www.cnblogs.com/' st = GetCnblogs(url)
pycharm运行截图
接下来获取每篇文章的具体内容,样式,图片
47745
46235
37110
34627
29229
25886
24745
19863
19417
17908
5716°
6315°
5835°
5888°
6984°
5829°
5846°
6361°
6316°
7673°