爬虫入门之爬取全唐诗并写入数据库

学习爬虫有一段时间了,今天想在此写一篇基于新手对爬虫入门的理解和初级爬虫的构建的文章。说白了,这篇文章,是写给比我还菜的人看的。别看了,说的就是你。

一个简单的爬虫构建我们采取一个简单的思路:

抓取网页

本次我们要抓取的页面是全唐诗,它的首页长这样:


全唐诗首页

依次点进去查看前几个页面的url,我们就会发现这些页面之间的规律:


李世民页

李治页

末尾页

好了,经过简单的观察,我们发现这些页面的url有一个字段是从0001增长到了0900,一共九百页,而其他地方则没有变化,这就好办了!但是也不要认为这个爬虫就这么简单,这些页面要抓取就是一整页,如何把这一整页诗词抽离出每首诗并写入数据库呢?接下来开始写爬虫

def gethtml(self,url):
        try :
            response = requests.get(url, headers=self.headers)
            response.encoding = 'gb18030'
        except :
            pass
        else :
            html = lxml.html.fromstring(response.text)
        finally:
            return html

这个方法是专门用来抓取网页源代码的,它接受一个网页URL作为参数,将网页源码转换为html元素并返回,并且随时准备被再次调用,至于response的编码,这里采取了gb18030,因为古诗词里面的生僻字太多了,另外再说一句,爬虫新手最头疼的问题编码可能算一个,采用requests库的时候,我们一般调用网页自身的编码方式来给网页的响应流编码:

response.encoding = response.apparent_encoding

但本教程是个例外,因为古诗词里面的生僻字实在是太多了~~~

抽取元素

抽取元素我们使用xpath,高效又简洁,正则表达式和beautifulsoup我都尝试过,但始终不如xpath深入我心。
检查网页源代码,我们只要获取DIV标签下面的文本就好了


检查元素
page = html.xpath('.//div/text()')

数据处理

上面我说过,这一页诗拿下来我们需要对其做数据抽取,这个时候不着急写代码,应该停下来认真观察拿到的诗文,选择一个最好的规则应用到其中,做到最优化的从诗文集合里分离单首诗文。这里我们注意到,每首诗的标题以「」包围的,我们的规则是上一个包含「」的行到下一个包含「」的行之间的内容为一首诗,然后再把「」里的诗名跟后面的作者都抽离出来,最终写入数据库,代码如下:

import csv
import pymysql
conn = pymysql.connect(host='localhost',port=3306,user='root',password='xxxx',db='xxx',charset='utf8')
cur = conn.cursor()
with open('tangshi.txt','r+',encoding='utf8') as f:
    with open('tangshi.csv','w+',encoding='utf8') as csvfile:
        writer = csv.writer(csvfile)
        items = f.readlines()
        lst = []
        for index, item in enumerate(items):
            if '」' in item:
                lst.append(index)   #存放了所有标题的索引
        for index, item in enumerate(lst):  #以索引-值 的形式遍历列表
            lst2 = items[item].split('「')
            author = lst2[-1].split('」')[-1]
            title = lst2[-1].split('」')[-2]
            if items[lst[index]] != items[lst[-1]]:    #如果这个标题不是最后一个
                context = items[lst[index]+1:lst[index+1]]
                context = ''.join([i.strip() for i in content if i ])       #做列表转字符串的处理
            else:
                context = items[lst[index]+1:]    #否则诗文是该标题到此文本的末尾
                context = ''.join([i.strip() for i in context if i])
            sql = 'insert into tangshi(title,author,context) values(%s,%s,%s)'
            cur.execute(sql, (title.strip(),author.strip(),context.strip()))
            conn.commit()
cur.close()
conn.close()

说到最后,我把爬虫的源代码贴在这里,python环境3.5,应该可以直接运行。时间仓促加上语言不够精炼,可能有些地方说的不够明白,请大家见谅,也欢迎读者提出疑问或者献上你宝贵的意见。下回见!

import requests
import lxml.html

class myspider():
    #定义内置方法,跟随类一起创建,全局变量一般在此方法下声明
    def __init__(self):
        user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 \
                    (KHTML, like Gecko) Chrome/62.0.3202.62 Safari/537.36'
        self.headers = {'User-Agent':user_agent}
        
    #定义获取相应url的html
    def gethtml(self,url):
        try :
            response = requests.get(url, headers=self.headers)
            response.encoding = 'gb18030'
        except :
            pass
        else :
            html = lxml.html.fromstring(response.text)
        finally:
            return html
    
    def getpage(self,url,num):
        with open('D:/{0}.txt'.format(num[1]),'w',encoding='utf8') as f : 
            for i in range(1,num[0]):
                print('正写入第{0}页'.format(i))
                s = str(i).zfill(4)
                print(s)
                ur =  url.format(s)
                html = self.gethtml(ur)
                print(ur)
                page = html.xpath('.//div/text()')
                for j in page :
                    if j : 
                        j.strip('\n')
                        f.write(j)
            print('写入完毕')

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

推荐阅读更多精彩内容