spider csdn博客和quantstart文章

功能

  1. 提取csdn博客文章
  2. 提取quantstart.com 博客文章, Micheal Hall-Moore 创办的网站

特色功能就是: 想把原来文章里的格式/样式(段落, 标题等等排版信息)保留到word文档里. 不仅仅是把文本提取出来.

目前能够全部得到文章信息. 而且博文里的段落和小标题信息也都保留了下来

TODO:

把它们写入word文档, 同时也要保留段落以及样式信息.

(转码到docx的部分留到以后实现)

遇到的问题以及解决办法

csdn博文用常规的requests库, 得到的是乱码.

多次尝试了指定编码, 也没有得到正解.

无奈只好改用selenium这个大笨蛋获取.

如果读者朋友知道requests的实现方案, 请不吝赐教.

关于用webdriver定位页面元素的技巧:

用wait...untill 组合手段来解决. 完美解决无法定位问题/或者简单设定超时等等时间.

WebDriverWait(brower, timeOut).until(lambda x: x.title)

WebDriverWait(brower, timeOut).until(lambda x: x.page_source)

WebDriverWait(brower, timeOut).until(lambda x: x.find_element_by_class('abc'))

截图

代码

v 0.2



import os; type(os)
import time; type(time)
import re
anys = '.*?' # 任意长的字符串, 贪婪型的 import random; type(random) import requests
from lxml import etree
from selenium import webdriver
chrome_options = webdriver.ChromeOptions()
chrome_options.binary_location = r'C:\Users\Administrator\AppData\Roaming\360se6\Application\360se.exe'
chrome_options.add_argument(r'--lang=zh-CN') # 这里添加一些启动的参数 import logging
logging.basicConfig(level=logging.INFO,
format= '%(asctime)s - %(name)s - %(levelname)s : %(message)s',
#format='%(asctime)s %(filename)s [line:%(lineno)d] %(levelname)s %(message)s',
)
logger = logging.getLogger(__name__) #logger.info("Start print log")
#logger.debug("Do something")
#logger.warning("Something maybe fail.")
#logger.info("Finish") from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
type(By)
type(EC) #%% def get_it_wait_untill(browser, element_func='title', sleep_time=80, arg=''):
'''
selenium内核的锁定页面元素, 然后取之. 比如:
获取网页标题
获取整个网页的源文件
获取指定页面元素:
by_id
by_xpath
Example:
>>> get_it_wait_untill(browser, 'title')
>>> get_it_wait_untill(browser, 'page_source')
>>> get_it_wait_untill(browser, element_func='find_element_by_id',
arg='content_views',
)
>>> get_it_wait_untill(browser, element_func='find_element_by_xpath',
arg='//section[@class="content article-content"]',
)
'''
prop = str(type(getattr(browser, element_func))) if prop == "<class 'str'>":
element = WebDriverWait(browser, sleep_time).until(
lambda x: getattr(x, element_func)
)
#elif callable(getattr(browser, element_func)):
elif prop == "<class 'method'>":
element = WebDriverWait(browser, sleep_time).until(
lambda x: getattr(x, element_func)(arg)
) return element #%% def get_quantstart_article(
url = 'https://www.quantstart.com/articles/Beginners-Guide-to-Quantitative-Trading'
,
sleep_time=40
,
kernel='requests', # or 'selenium'
xpath = '//section[@class="content article-content"]'
,
):
'''quantstart blog by: Micheal Hall-Moore
'''
#Beginner's Guide to Quantitative Trading | QuantStart
logger.info(f'当前的url: {url}') if kernel=='requests':
headers = {
'User-Agent': 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)',
# 'Cookie' : 'acw_tc=2760820715764664133076924e81d61fc0916132e54d88a183dbc0bd00aa01; acw_sc__v2=5df6f7edcaabd3ef5262a7a3d573f5675b385aec; uuid_tt_dd=10_17296990010-1576466413788-862921; dc_session_id=10_1576466413788.893537; Hm_lvt_6bcd52f51e9b3dce32bec4a3997715ac=1576466384; Hm_ct_6bcd52f51e9b3dce32bec4a3997715ac=6525*1*10_17296990010-1576466413788-862921; announcement=%257B%2522isLogin%2522%253Afalse%252C%2522announcementUrl%2522%253A%2522https%253A%252F%252Fblogdev.blog.csdn.net%252Farticle%252Fdetails%252F103053996%2522%252C%2522announcementCount%2522%253A0%252C%2522announcementExpire%2522%253A3600000%257D; Hm_lpvt_6bcd52f51e9b3dce32bec4a3997715ac=1576466781; c-login-auto=2; dc_tos=q2l5ox',
}
try:
resp = requests.get(url, params=headers)
if resp.status_code==200:
logger.info(f'get网络请求的响应ok!!!, 响应的编码是{resp.encoding}')
html = resp.text
#html2 = str(resp.content, encoding='utf-8')
#is_eqs = html==html2; print(is_eqs) tree = etree.HTML(html)
article_tree = tree.xpath(xpath)[0]
article_html = etree.tostring(article_tree,); type(article_html)
article_unicode = etree.tounicode(article_tree)
article_unicode = re.findall('<section.*?(<p>.*?)</section>',
article_unicode, re.S)[0]
logger.info(article_unicode[-100:])
return article_unicode.strip()
else:
logger.info(f'responce status code: {resp.status_code}')
logger.error('requests.get()网络连接/网络请求不正常!!!')
return False except Exception as ee:
logger.error(f'Exception: {ee}')
return False elif kernel=='selenium':
browser = webdriver.Chrome(options=chrome_options)
#timeout_wait = WebDriverWait(browser, 2*5) # 10sec
browser.get(url)
timeout_wait = WebDriverWait(browser, 2*5) # 10sec;
type(timeout_wait) #title = browser.title
title = get_it_wait_untill(browser, 'title')
logger.info(f'网页的标题是: {title} ')
html = get_it_wait_untill(browser, 'page_source') # 需要花点时间 article_webelement = browser.find_element_by_xpath(xpath)
article_text = article_webelement.text; type(article_text)
logger.info('网页源码的长度和博文的长度分别是: {1} {0}'.
format(len(article_text), len(html))
) # pattern = '<title>(.*?)</title>'
# pattern = '<p>(.*?)</p>'
pattern = '</style></form>' + \
'(.*?)' + \
'<div class="col-md-4 book-card order-md-1">'
a = re.findall(pattern, html, re.S)
a = a[0] a = re.findall(f'{anys}(<p>{anys})</section>{anys}', a, re.S)[0] return a
else:
logger.error('出错了!!! 你必须指定正确的内核. 或者selenium 或者requests!')
return False #%%
def get_csdn_blog(
url='https://blog.csdn.net/Lili_0820/article/details/70155949'
,
sleep_time=40
,
):
'''
爬取csdn blog文章
参数:
url: str,
sleep_time: int, wait time in seconds
'''
logger.info(f'当前的url: {url}')
browser = webdriver.Chrome(options=chrome_options)
#timeout_wait = WebDriverWait(browser, 2*5) # 10sec
browser.get(url)
timeout_wait = WebDriverWait(browser, sleep_time) # 10sec;
type(timeout_wait) '''
我们需要确保: 网页信息已经全部加载, 否则可能提取不到有用信息. Sets a sticky timeout to implicitly wait for an element to be found,
or a command to complete.
This method only needs to be called one time per session.
当浏览器(webdriver实例)在定位元素的时候,
我们可以设置一个隐式的超时等待时间,
如果超过这个设定的时间还不能锁定元素, 那么就报错或者继续执行.
本方法在整个对话期内, 只需调用一次. '''
browser.implicitly_wait(200)
'''
i=0
while 1: # 有可能是一个无限循环, 改用: wait...untill
title = browser.title
# selenium 取数据时的等待时间间隔是: 0.5sec
# poll_frequency=0.5
i+=1
logger.info(f'提取网页标题: 定位title元素的次数: \n{i} {title}')
if len(title)>=5 :
break
'''
title = WebDriverWait(browser, sleep_time).until(lambda x: x.title)
logger.info(f'提取网页标题: {title}') html= WebDriverWait(browser, sleep_time).until(lambda x: x.page_source)
#html = browser.page_source
#需要花点时间
#time.sleep(sleep_time) # 太粗暴简单了
content = browser.find_element_by_id('content_views') # selenium.webelement
text = content.text; type(text)
logger.info('网页源码的长度和博文的长度分别是: {1} {0}'.
format(len(text), len(html))
) pattern = 'id="content_views" class="markdown_views.*?>' + \
'(.*?)' + \
'<link href="https://csdnimg.cn/release/' + \
'phoenix/mdeditor/markdown_views'
a = re.findall(pattern, html, re.S)
a = a[0]
a = re.findall(f'{anys}(<p>{anys})</div>{anys}', a, re.S)[0] '''
tree = etree.HTML(html)
tree_cv = tree.xpath('//div[@id="content_views"]')[0]
txt = tree_cv.xpath('*/text()')
txt2 = tree_cv.xpath('*//text()')
txt22 = '\n'.join(txt2) html_cv = etree.tostring(tree_cv)
'''
browser.close()
return a if __name__=='__main__':
pass
# blog2r=get_quantstart_article()
# blog2r=get_quantstart_article(kernel='requests')
# blog2r=get_quantstart_article(url='http://www.ba', kernel='requests')
# blog2s=get_quantstart_article(kernel='selenium')
# blog2=get_quantstart_article(kernel='req') # blog1 = get_csdn_blog(sleep_time=80)

v 0.1



import os; type(os)
import time
import re
anys = '.*?' # 任意长的字符串, 贪婪型的 import random; type(random) import requests
from lxml import etree
from selenium import webdriver
chrome_options = webdriver.ChromeOptions()
chrome_options.binary_location = r'C:\Users\Administrator\AppData\Roaming\360se6\Application\360se.exe'
chrome_options.add_argument(r'--lang=zh-CN') # 这里添加一些启动的参数 import logging
logging.basicConfig(level=logging.INFO,
format= '%(asctime)s - %(name)s - %(levelname)s : %(message)s',
#format='%(asctime)s %(filename)s [line:%(lineno)d] %(levelname)s %(message)s',
)
logger = logging.getLogger(__name__) #logger.info("Start print log")
#logger.debug("Do something")
#logger.warning("Something maybe fail.")
#logger.info("Finish") from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
type(By)
type(EC) def get_quantstart_article(
url = 'https://www.quantstart.com/articles/Beginners-Guide-to-Quantitative-Trading'
,
sleep_time=40
,
kernel='requests', # or 'selenium'
xpath = '//section[@class="content article-content"]'
,
):
'''quantstart blog by: Micheal Hall-Moore
'''
#Beginner's Guide to Quantitative Trading | QuantStart
logger.info(f'当前的url: {url}') if kernel=='requests':
headers = {
'User-Agent': 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)',
# 'Cookie' : 'acw_tc=2760820715764664133076924e81d61fc0916132e54d88a183dbc0bd00aa01; acw_sc__v2=5df6f7edcaabd3ef5262a7a3d573f5675b385aec; uuid_tt_dd=10_17296990010-1576466413788-862921; dc_session_id=10_1576466413788.893537; Hm_lvt_6bcd52f51e9b3dce32bec4a3997715ac=1576466384; Hm_ct_6bcd52f51e9b3dce32bec4a3997715ac=6525*1*10_17296990010-1576466413788-862921; announcement=%257B%2522isLogin%2522%253Afalse%252C%2522announcementUrl%2522%253A%2522https%253A%252F%252Fblogdev.blog.csdn.net%252Farticle%252Fdetails%252F103053996%2522%252C%2522announcementCount%2522%253A0%252C%2522announcementExpire%2522%253A3600000%257D; Hm_lpvt_6bcd52f51e9b3dce32bec4a3997715ac=1576466781; c-login-auto=2; dc_tos=q2l5ox',
}
try:
resp = requests.get(url, params=headers)
if resp.status_code==200:
logger.info(f'get网络请求的响应ok!!!, 响应的编码是{resp.encoding}')
html = resp.text
#html2 = str(resp.content, encoding='utf-8')
#is_eqs = html==html2; print(is_eqs) tree = etree.HTML(html)
article_tree = tree.xpath(xpath)[0]
article_html = etree.tostring(article_tree,); type(article_html)
article_unicode = etree.tounicode(article_tree)
article_unicode = re.findall('<section.*?(<p>.*?)</section>',
article_unicode, re.S)[0]
logger.info(article_unicode[-100:])
return article_unicode.strip()
else:
logger.info(f'responce status code: {resp.status_code}')
logger.error('requests.get()网络连接/网络请求不正常!!!')
return False except Exception as ee:
logger.error(f'Exception: {ee}')
return False elif kernel=='selenium':
browser = webdriver.Chrome(options=chrome_options)
#timeout_wait = WebDriverWait(browser, 2*5) # 10sec
browser.get(url)
timeout_wait = WebDriverWait(browser, 2*5) # 10sec;
type(timeout_wait) title = browser.title
print('网页的标题是: ', title)
html = browser.page_source # 需要花点时间
time.sleep(sleep_time)
article_webelement = browser.find_element_by_xpath(xpath)
article_text = article_webelement.text; type(article_text)
print('网页源码的长度和博文的长度分别是: {1} {0}'.
format(len(article_text), len(html))
) # pattern = '<title>(.*?)</title>'
# pattern = '<p>(.*?)</p>'
pattern = '</style></form>' + \
'(.*?)' + \
'<div class="col-md-4 book-card order-md-1">'
a = re.findall(pattern, html, re.S)
a = a[0] a = re.findall(f'{anys}(<p>{anys})</section>{anys}', a, re.S)[0] return a
else:
logger.error('出错了!!! 你必须指定正确的内核. 或者selenium 或者requests!')
return False #%%
def get_csdn_blog(
url='https://blog.csdn.net/Lili_0820/article/details/70155949'
,
sleep_time=40
,
):
'''
爬取csdn blog文章
参数:
url: str,
sleep_time: int, wait time in seconds
'''
logger.info(f'当前的url: {url}')
browser = webdriver.Chrome(options=chrome_options)
#timeout_wait = WebDriverWait(browser, 2*5) # 10sec
browser.get(url)
timeout_wait = WebDriverWait(browser, sleep_time) # 10sec;
type(timeout_wait) '''
我们需要确保: 网页信息已经全部加载, 否则可能提取不到有用信息. Sets a sticky timeout to implicitly wait for an element to be found,
or a command to complete.
This method only needs to be called one time per session.
当浏览器(webdriver实例)在定位元素的时候,
我们可以设置一个隐式的超时等待时间,
如果超过这个设定的时间还不能锁定元素, 那么就报错或者继续执行.
本方法在整个对话期内, 只需调用一次. '''
browser.implicitly_wait(200)
'''
i=0
while 1: # 有可能是一个无限循环, 改用: wait...untill
title = browser.title
# selenium 取数据时的等待时间间隔是: 0.5sec
# poll_frequency=0.5
i+=1
logger.info(f'提取网页标题: 定位title元素的次数: \n{i} {title}')
if len(title)>=5 :
break
'''
title = WebDriverWait(browser, sleep_time).until(lambda x: x.title)
logger.info(f'提取网页标题: {title}') html= WebDriverWait(browser, sleep_time).until(lambda x: x.page_source)
#html = browser.page_source
#需要花点时间
#time.sleep(sleep_time) # 太粗暴简单了
content = browser.find_element_by_id('content_views') # selenium.webelement
text = content.text; type(text)
logger.info('网页源码的长度和博文的长度分别是: {1} {0}'.
format(len(text), len(html))
) pattern = 'id="content_views" class="markdown_views.*?>' + \
'(.*?)' + \
'<link href="https://csdnimg.cn/release/' + \
'phoenix/mdeditor/markdown_views'
a = re.findall(pattern, html, re.S)
a = a[0]
a = re.findall(f'{anys}(<p>{anys})</div>{anys}', a, re.S)[0] '''
tree = etree.HTML(html)
tree_cv = tree.xpath('//div[@id="content_views"]')[0]
txt = tree_cv.xpath('*/text()')
txt2 = tree_cv.xpath('*//text()')
txt22 = '\n'.join(txt2) html_cv = etree.tostring(tree_cv)
'''
browser.close()
return a if __name__=='__main__':
# blog2r=get_quantstart_article()
# blog2r=get_quantstart_article(kernel='requests')
# blog2r=get_quantstart_article(url='http://www.ba', kernel='requests')
# blog2s=get_quantstart_article(kernel='selenium')
# blog2=get_quantstart_article(kernel='req') blog1 = get_csdn_blog(sleep_time=80)

spider csdn博客和quantstart文章的更多相关文章

  1. 公告:CSDN博客频道新功能正式上线!

    各位尊敬的CSDN用户: 你们好! 为了更好的服务于用户,CSDN博客最新推出如下功能: 1.取消开通博客3天才能发布博文的限制,博客开通之后即可发表博文 2.博客文章增加自定义摘要功能    在发表 ...

  2. JAVA爬虫挖取CSDN博客文章

    开门见山,看看这个教程的主要任务,就去csdn博客,挖取技术文章,我以<第一行代码–安卓>的作者为例,将他在csdn发表的额博客信息都挖取出来.因为郭神是我在大学期间比较崇拜的对象之一.他 ...

  3. [置顶] 很荣幸被选为2013年度 CSDN博客之星评选,如果觉得我的文章可以,请投我一票!

    亲爱的小伙伴们,很荣幸我被选为<2013年度CSDN博客之星候选人>,希望大家多多支持,geekguy会继续努力,为大家奉献更好的文章. 投票地址:http://vote.blog.csd ...

  4. Python爬取CSDN博客文章

    0 url :http://blog.csdn.net/youyou1543724847/article/details/52818339Redis一点基础的东西目录 1.基础底层数据结构 2.win ...

  5. Python爬虫小实践:爬取任意CSDN博客所有文章的文字内容(或可改写为保存其他的元素),间接增加博客访问量

    Python并不是我的主业,当初学Python主要是为了学爬虫,以为自己觉得能够从网上爬东西是一件非常神奇又是一件非常有用的事情,因为我们可以获取一些方面的数据或者其他的东西,反正各有用处. 这两天闲 ...

  6. 巨高兴,偶的文章 “如何在服务器上配置ODBC来访问本机DB2for Windows服务器”被推荐至CSDN博客首页

    非常高兴,偶的文章 "如何在服务器上配置ODBC来访问本机DB2for Windows服务器"被推荐至CSDN博客首页,截图留念.                  文章被推荐在C ...

  7. CSDN博客文章的备份及导出电子书CHM

    需要用到的工具集合下载:http://download.csdn.net/source/2881423 在CSDN.百度等写博客文章的应该很多,很多时候担心服务器有一天突然挂了,或者担心自己的号被封了 ...

  8. CSDN博客的文章分类和战略规划

    CSDN原创文章已经有300多篇了,现在已经整理了好多个分类目录了. 今天,特别向大家介绍下,每个分类的含义和规划. CSDN博客是我的一个重要的自媒体,也是我的一个战略实践. 我会精心维护这个博客, ...

  9. 利用爬虫爬取指定用户的CSDN博客文章转为md格式,目的是完成博客迁移博文到Hexo等静态博客

    文章目录 功能 爬取的方式: 设置生成的md文件命名规则: 设置md文件的头部信息 是否显示csdn中的锚点"文章目录"字样,以及下面具体的锚点 默认false(因为csdn中是集 ...

随机推荐

  1. python基础(输出、变量、常量、数据类型、流程控制)

    输出 print print("Hello World!") # python2 和 python3 的区别 # python2 # coding:utf-8 print 123 ...

  2. 通信网络 ccf

    试题编号: 201709-4 试题名称: 通信网络 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 某国的军队由N个部门组成,为了提高安全性,部门之间建立了M条通路,每条通路只 ...

  3. windows服务器nginx日志分割

    编写一个bat文件 @echo off rem @echo off rem 取1天之前的日期 echo wscript.echo dateadd(,date) >%tmp%\tmp.vbs fo ...

  4. win10 ubuntu 双系统启动顺序设置

    之前安装ubuntu的时候就遇到过这个问题, 当时解决了,设置成开始可以选择启动ubuntu系统还是win系统. 但是过了好久后又忘记了,最近win10开了一次安全模式启动后,一开机就是win10,u ...

  5. 洛谷P1083 [NOIP2012提高组Day2T2]借教室

    P1083 借教室 题目描述 在大学期间,经常需要租借教室.大到院系举办活动,小到学习小组自习讨论,都需要向学校申请借教室.教室的大小功能不同,借教室人的身份不同,借教室的手续也不一样. 面对海量租借 ...

  6. LUOGU 2593 : [Zjoi2006] 超级麻将

    传送门 解题思路 直接爆搜全T..状态数太多了,所以我们考虑贪心+剪枝.贪心:先拿三个连着的,再拿四个一样的,再拿三个一样的,最后拿两个一样的这样的搜索顺序最优,两个的放最后是因为只要这样的一个,三个 ...

  7. Eclipse Git插件切换分支的时候不要Reset

    今天做了一件蠢事,我在当前分支上改了很多代码,后来切换分支的时候,有一个文件有冲突,eclipse提示这个文件冲突,我可以选择commit/stash/reset,我一看这个文件没什么关系,不需要提交 ...

  8. vue使用填坑之生命周期钩子的 this 上下文

    每个Vue实例在被创建的时候都需要经过一系列的初始过程,如设置数据监听,编译模版,将实例挂载到DOM并在数据变化的时候更新DOM.在这个过程中,也会运行一些叫生命周期钩子的函数.如created, m ...

  9. pyenv虚拟环境管理python多版本和软件库

    可能大家在日常工作中会遇到这么个问题,现在基本的linux系统都是自带老版本的python2.7.x版本,我又不想用老版本,但直接升级可能会出问题,或是依赖老版本的程序就运行不了,有没办法能安装3.x ...

  10. 数据库---JDBC的解析

    一.JDBC是什么? JDBC:Java Database Connectivity(Java数据库连接池).指定了统一的访问各种关系型数据库的标准接口-----桥梁作用.  功能:[与数据库建立连接 ...