栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

python3+sqlite3+多线程爬取某网站文章

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

python3+sqlite3+多线程爬取某网站文章

  • 之前有爬取过某网站内容,抓取该网站发表的文章内容并保存到数据库,最近又想学一些爬虫方面的知识,所以把之前写的内容翻出来写一写笔记。

  • 首先使用谷歌浏览器分析网页源码,因为该网站是并没有涉及什么js、css渲染等动态网页,所以爬取的过程相对简单。

  • 爬取了该网站的标题、作者、发表时间、评论数、第一张大图的url和内容,然后格式化数据并保存到sqlite3

  • 其过程的实现很简单,就是简单的URL抓包提取网页,然后使用了正则表达式来提取数据,然后进行一些错误的判断和改进,并没有使用到太高级的爬虫技巧,还在继续学习之中。

  • 源码如下:

# -*-coding:utf-8-*-import urllib.requestimport reimport sqlite3import timeimport randomimport threadingimport urllib.errorimport sysimport socketimport iofrom datetime import datetimeclass Article(object):
    def __init__(self):
        self.url="http://wallstreetcn.com/"
        self.removeP=re.compile('

')#用来提取正文内容         self.removeRight=re.compile('class=".*?"|align=".*?"|>')         self.removeStrong=re.compile("|")         self.removeAddr=re.compile('|')         self.replaceBR=re.compile('

|
|
')         self.removeImg=re.compile('| {1,7}|&.*?;')         self.removeExtraTag=re.compile('<.*?>|style=".*?"|value=".*?"')         self.removeNoneLine=re.compile('\n+')    def get_content(self,article):         #使用正则表达式匹配出标题、作者、日期、内容、第一张大图的url、评论数         title = re.findall(r'(.*?)',article,re.S)         author=re.search(r'(.*?)target="_blank">(.*?)(.*?)',article,re.S)         post_at=re.findall(r'(.*?)',article,re.S)         time=post_at[0]         year=time[:4]         month=time[5:7]         day=time[8:10]         hour=time[12:]#对有中文时间格式处理,返回值为datetime格式         p_content=re.findall(r'',article,re.S)#正文内容有多种类型,分别匹配         span_content=re.findall(r'(.*?)',article,re.S)        if p_content==None:             content=span_content        else:             content=p_content         str_data=''.join(content[:-4])         removed_p=re.sub(self.removeP,'\n',str_data)         removed_strong=re.sub(self.removeStrong,'',removed_p)         removed_addr=re.sub(self.removeAddr,'',removed_strong)         removed_br=re.sub(self.replaceBR,'\n',removed_addr)         removed_img=re.sub(self.removeImg,'',removed_br)         removed_tag=re.sub(self.removeExtraTag,'',removed_img)         removed_right=re.sub(self.removeRight,'',removed_tag)         content=re.sub(self.removeNoneLine,'\n',removed_right)         img_1=re.search(r'(.*?)',article,re.S)                 try:            if img==None and comment_count==None:#有可能文章没有图片和评论,考虑以下几种情况                 return str(title[0]),str(author.group(2)),datetime.strptime(year+'-'+month+'-'+day+' '+hour,'%Y-%m-%d %H:%M:%S'),''.join(content),None,0             elif img!=None and comment_count==None:                return str(title[0]),str(author.group(2)),datetime.strptime(year+'-'+month+'-'+day+' '+hour,'%Y-%m-%d %H:%M:%S'),''.join(content),str(img),0             elif img==None and comment_count!=None:                return str(title[0]),str(author.group(2)),datetime.strptime(year+'-'+month+'-'+day+' '+hour,'%Y-%m-%d %H:%M:%S'),''.join(content),None,int(comment_count[0])            else:                return str(title[0]),str(author.group(2)),datetime.strptime(year+'-'+month+'-'+day+' '+hour,'%Y-%m-%d %H:%M:%S'),''.join(content),str(img),int(comment_count[0])        except Exception as e:            pass     def create_table(self):         conn=sqlite3.connect('article.db')        #如果不存在一个art表,新建一个art表         conn.execute("CREATE TABLE IF NOT EXISTS art(title varchar(80) PRIMARY KEY not null, author varchar(10),post_at TEXT not null,content varchar(255) not null,img varchar(20) ,comment_count integer);")         conn.close()    def save_content(self,title,author,post_at,content,img,comment_count):         #连接并保存到数据库         conn=sqlite3.connect('article.db')         conn.execute("INSERT INTO art (title,author,post_at,content,img,comment_count)values(?,?,?,?,?,?)",(title,author,post_at,content,img,comment_count))         result=conn.execute("SELECT * FROM art")        return list(result)         conn.close()    def spider(self):         cou=1         for i in random.sample(range(19,247271),10000):#随机生成url,数字可以任意             try:                try:                     full_url=self.url+'node'+'/'+str(i)#URL格式                     page = urllib.request.urlopen(full_url,timeout=5)#设置请求时间限制                     pages= page.read().decode('utf-8','ignore')                     lst=self.get_content(pages)                    #self.save_content(lst[0],lst[1],lst[2],lst[3],lst[4],lst[5])#不打印出结果                     print(self.save_content(lst[0],lst[1],lst[2],lst[3],lst[4],lst[5]))#打印出结果                     print('Downloaded Successfully...\n')                     cou+=1                     time.sleep(1)                    if cou>300:#控制爬取300篇文章,可以自行调节文章数量,量力而为                         sys.exit()                    else:                        continue                 except Exception as e:                    pass             except socket.error as e:                pass                           def main(self):         #多线程爬取         my_thread = threading.Thread(target = self.spider)         my_thread.start()         my_thread.join()     if __name__ == '__main__':     a=Article()#实例化     a.create_table()     a.main()
  • 到此,一个小小的spider就完成了,就可以实现文章的抓取和保存到数据库了,在dos下的显示如下所示。

  • 最后,由于是第一次写爬虫,不足之处肯定还有很多,欢迎来挑刺,洗耳恭听,一直在学习与进步当中,继续,共勉。

作者:HalShaw
链接:https://www.jianshu.com/p/01c43def734d


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/223349.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号