码迷,mamicode.com
首页 > 数据库 > 详细

【Python】理想论坛爬虫,先爬主贴,再爬主贴中子贴,将发帖人,发帖时间等录入MySql数据库

时间:2018-04-04 16:11:57      阅读:237      评论:0      收藏:0      [点我收藏+]

标签:thread   技术分享   def   ddt   pre   strong   split   utf-8   5.5   

这回两个爬虫协助作业,论坛爬虫先爬主贴,爬到主贴后启动帖子爬虫爬子贴。

代码多点了:

# 论坛爬虫,用于爬取主贴再爬子贴
from bs4 import BeautifulSoup
import requests
import threading
import re
import pymysql

user_agent=Mozilla/4.0 (compatible;MEIE 5.5;windows NT)
headers={User-Agent:user_agent}

# 论坛爬虫类(多线程)
class forumCrawler(threading.Thread):
    def __init__(self,name,url):
        threading.Thread.__init__(self,name=name)
        self.name=name
        self.url=url
        self.infos=[]
    
    def run(self):
        print("线程"+self.name+"开始爬取页面"+self.url);

        try:
            rsp=requests.get(self.url,headers=headers)
            soup= BeautifulSoup(rsp.text,html.parser,from_encoding=utf-8)
            #print(rsp.text); # rsp.text是全文

            # 找出span
            for spans in soup.find_all(span,class_="forumdisplay"):
                #找出link
                for link in spans.find_all(a):
                    if link and link.get("href"): 
                        #print(link.get("href"))
                        #print(link.text+‘\n‘)
                        topicLink="http://www.55188.com/"+link.get("href")

                        tc=topicCrawler(name=self.name+_tc#+link.get("href"),url=topicLink)
                        tc.start()


        except Exception as e:
            print("线程"+self.name+"发生异常。")# 不管怎么出现的异常,就让它一直爬到底
            print(e);

# 帖子爬虫类(多线程)
class topicCrawler(threading.Thread):
    def __init__(self,name,url):
        threading.Thread.__init__(self,name=name)
        self.name=name
        self.url=url
        self.infos=[]
    
    def run(self):
        while(self.url!="none"):
            print("线程"+self.name+"开始爬取页面"+self.url);

            try:
                rsp=requests.get(self.url,headers=headers)
                self.url="none"#用完之后置空,看下一页能否取到值
                soup= BeautifulSoup(rsp.text,html.parser,from_encoding=utf-8)
                #print(rsp.text); # rsp.text是全文

                # 找出一页里每条发言
                for divs in soup.find_all(div,class_="postinfo"):
                    #print(divs.text) # divs.text包含作者和发帖时间的文字
                    
                    # 用正则表达式将多个空白字符替换成一个空格
                    RE = re.compile(r(\s+))
                    line=RE.sub(" ",divs.text)

                    arr=line.split( )

                    #print(len(arr)) 
                    arrLength=len(arr)

                    if arrLength==7:
                        info={楼层:arr[1],
                              作者:arr[2].replace(只看:,‘‘),
                              日期:arr[4],
                              时间:arr[5]}
                        self.infos.append(info);
                    elif arrLength==8:
                        info={楼层:arr[1],
                              作者:arr[2].replace(只看:,‘‘),
                              日期:arr[5],
                              时间:arr[6]}
                        self.infos.append(info);



                #找下一页所在地址
                for pagesDiv in soup.find_all(div,class_="pages"):
                    for strong in pagesDiv.find_all(strong):
                        print(当前为第+strong.text+)

                        # 找右边的兄弟节点
                        nextNode=strong.next_sibling
                        if nextNode and nextNode.get("href"): # 右边的兄弟节点存在,且其有href属性
                            #print(nextNode.get("href"))
                            self.url=http://www.55188.com/+nextNode.get("href")


                if self.url!="none":
                    print("有下一页,线程"+self.name+"前往下一页")
                    continue
                else:
                    print("无下一页,线程"+self.name+爬取结束,开始打印...)
                    
                    for info in self.infos:
                        print(\n)
                        for key in info:
                            print(key+":"+info[key])

                    print("线程"+self.name+打印结束.)

                    insertDB(self.name,self.infos)


            except Exception as e:
                print("线程"+self.name+"发生异常。重新爬行")# 不管怎么出现的异常,就让它一直爬到底
                print(e);
                continue

# 数据库插值
def insertDB(crawlName,infos):
    conn=pymysql.connect(host=127.0.0.1,user=root,passwd=12345678,db=test,charset=utf8)
    

    for info in infos:
        sql="insert into test.topic(floor,author,tdate,ttime,crawlername,addtime) values (‘"+info[楼层]+"‘,‘"+info[作者]+"‘,‘"+info[日期]+"‘,‘"+info[时间]+"‘,‘"+crawlName+"‘,now() )"
        print(sql)
        conn.query(sql)
    
    conn.commit()# 写操作之后commit不可少
    conn.close()


# 入口函数
def main():
    for i in range(1,10):
        url=http://www.55188.com/forum-8-+str(i)+.html
        tc=forumCrawler(name=fc#+str(i),url=url)
        tc.start()

# 开始
main()

输出太多就不贴了,把插入数据后的数据库展示一下:

技术分享图片

一会针对数据做个处理。

 

【Python】理想论坛爬虫,先爬主贴,再爬主贴中子贴,将发帖人,发帖时间等录入MySql数据库

标签:thread   技术分享   def   ddt   pre   strong   split   utf-8   5.5   

原文地址:https://www.cnblogs.com/xiandedanteng/p/8717506.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!