爬维基百科

https://en.wikipedia.org/wiki/Wikipedia
爬一个词相关的2层词
维基每个词条的url 是这样
https://en.wikipedia.org/wiki/
对应正则是 <a href="/wiki/([^:#=<>]?)".?</a>

比如 Wikipedia这个词 url是
https://en.wikipedia.org/wiki/Wikipedia

请求头



主要是 我是谁:
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36

拿到页面html , 异常也继续, 也记入爬过的list

 try:
        headers = \
            {
                'User-Agent': 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6'
            }

        r = requests.get("https://en.wikipedia.org/wiki/" + current_word, headers=headers)
        html = r.text
    except Exception as e:
        print('Failed downloading and saving', current_word)
        print(e)
        exist_url.append(current_word)
        return None

正则<a href="/wiki/([^:#=<>]?)".?</a> 找到相关的词条
要记录爬过的词, 防止爬重复了

  # 记录已经爬过的url
    exist_url.append(current_word)
    link_list = re.findall('<a href="/wiki/([^:#=<>]*?)".*?</a>', html)  # 本页面的维基url
    unique_list = list(set(link_list) - set(exist_url))  # 没爬过的

每个词记录到文件link_12-3.txt, 下一层,深度优先 递归爬2层

    for wordInThisPage in unique_list:

        g_writecount += 1
        output = "No." + str(g_writecount) + "\t Depth:" + str(depth) + "\t" + current_word + ' -> ' + wordInThisPage + '\n'
        # 输出到 文件link_12-3.txt
        with open('link_12-3.txt', "a+") as f:
            f.write(output)
            f.close()

        if depth < 2:# 递归
            scrappy(wordInThisPage, depth + 1)

深度优先完整代码

import requests
import re
import time

time1 = time.time()
exist_url = []  # 记录已经爬过的
g_writecount = 0


def scrappy(current_word, depth=1):

    # 全局变量要写 必须这样global
    global g_writecount

    print(current_word)

    try:
        headers = \
            {
                'User-Agent': 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6'
            }

        r = requests.get("https://en.wikipedia.org/wiki/" + current_word, headers=headers)
        html = r.text
    except Exception as e:
        print('Failed downloading and saving', current_word)
        print(e)
        exist_url.append(current_word)
        return None

    # 记录已经爬过的url
    exist_url.append(current_word)
    link_list = re.findall('<a href="/wiki/([^:#=<>]*?)".*?</a>', html)  # 本页面的维基url
    unique_list = list(set(link_list) - set(exist_url))  # 没爬过的

    for wordInThisPage in unique_list:

        g_writecount += 1
        output = "No." + str(g_writecount) + "\t Depth:" + str(depth) + "\t" + current_word + ' -> ' + wordInThisPage + '\n'
        # 输出到 文件link_12-3.txt
        with open('link_12-3.txt', "a+") as f:
            f.write(output)
            f.close()
        # 第一个关联词条 往下递归  深度优先
        if depth < 2:
            scrappy(wordInThisPage, depth + 1)


scrappy("Wikipedia")
time2 = time.time()
print ("Total time", time2 - time1)

广搜多线程

每一层, 尽量每个词开一个线程爬(如果线程池内线程不敢,就下一批)

#!/usr/bin/env python
# coding=utf-8
import threading
import requests
import re

# 作为锁
g_mutex = threading.Condition()


g_row_queue_word = []  # 下一层 等待爬取的word(它自己已经记入文件, 它相关的词汇还没记入
g_existWord = []  # 这里面的词, 它关联的词都已经记入文件了

g_write_count = 0  # 已记入的词条数


class Crawler:

    def __init__(self, word, threadnum):

        self.word = word
        self.thread_num = threadnum
        self.thread_pool = []

    def craw(self):

        g_row_queue_word.append(word)

        depth = 1

        while depth < 3:
            print('Searching depth ', depth, ' ...\n')
            self.download_all() # 这层全部爬完 并更新好下一层待爬词
            depth += 1

    # 把本层的词 用多线程爬完
    def download_all(self):

        global g_row_queue_word  # 待爬的词条
        had_craw_count = 0  # 已爬记录

        # 循环 直到这层的待爬词 都爬了
        while had_craw_count < len(g_row_queue_word):

            # 增加的线程到线程池允许的数量 或  词条需要的数量
            start_thread = 0
            while start_thread < self.thread_num and had_craw_count + start_thread < len(g_row_queue_word):
                self.download(g_row_queue_word[had_craw_count + start_thread], start_thread)
                start_thread += 1

            # 线程池里面的线程 运行完
            for thread in self.thread_pool:
                thread.join(30)

            had_craw_count += start_thread

        g_row_queue_word = []

    # 调用多线程爬虫
    def download(self, url, tid):

        craw_thread = CrawlerThread(url, tid)

        self.thread_pool.append(craw_thread)
        craw_thread.start()


class CrawlerThread(threading.Thread):  # 爬虫线程

    def __init__(self, word, tid):

        threading.Thread.__init__(self)
        self.word = word
        self.tid = tid

    # 把 word 页面里面出现的词条 写入文件, 已经写过的词记录一下g_existWord  页面本身 记入g_pages(下一个以此出发)
    def run(self):

        global g_mutex
        global g_write_count
        global g_row_queue_word

        write_file_words = []
        try:
            print(self.tid, "crawl ", self.word)
            headers = {
                'User-Agent': 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6'}
            r = requests.get("https://en.wikipedia.org/wiki/" + self.word, headers=headers)
            html = r.text

            link_list2 = re.findall('<a href="/wiki/([^:#=<>]*?)".*?</a>', html)
            unique_list2 = list(set(link_list2))

            for eachone in unique_list2:
                g_write_count += 1
                content2 = "No." + str(g_write_count) + "\t Thread" + str(
                    self.tid) + "\t" + self.word + '->' + eachone + '\n'
                with open('title2.txt', "a+") as f:
                    f.write(content2)
                    f.close()
                write_file_words.append(eachone)

        except Exception as e:

            print('Failed downloading and saving', self.word)
            print(e)
            return None

        # 原子操作
        g_mutex.acquire()
        g_row_queue_word = list(set(g_row_queue_word + write_file_words))
        g_existWord.append(self.word)
        g_mutex.release()


if __name__ == "__main__":
    word = "Wikipedia"
    thread_num = 5
    crawler = Crawler(word, thread_num)
    crawler.craw()  # 开爬

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容

  • # Python 资源大全中文版 我想很多程序员应该记得 GitHub 上有一个 Awesome - XXX 系列...
    小迈克阅读 2,956评论 1 3
  • http://www.jianshu.com/p/67683d26e644 一、基础篇1.1 JVM1.1.1. ...
    Albert陈凯阅读 534评论 0 6
  • 一、基础篇 1.1 JVM 1.1.1. Java内存模型,Java内存管理,Java堆和栈,垃圾回收 http:...
    最美的太阳WW阅读 689评论 0 1
  • 仍在加班中,在工作间歇,不期然就想写上这样一篇文字。 我们总是在处于忙忙碌碌中,为学习、为工作,也有可能不为什么,...
    秋叶瑟瑟阅读 731评论 0 0
  • 我性格一直是一个比较慢吞吞的人。哪怕心里面急急火火,手头也还是一点点在做。 不是别的,一直就深知自己其实是个笨蛋。...
    还在呢死胖纸阅读 212评论 0 3