Python Scrapy 爬取姓名大全数据

欢迎来我的个人博客:fizzyi

项目介绍

爬取地址: http://www.resgain.net/xmdq.html

爬取内容:为该网址下的所有姓氏和姓氏名字

爬取步骤:

  • 先爬取所有的姓氏,包括姓氏,姓氏的中文,每个姓氏的URL
  • 然后在进每一个姓氏的网址进去爬取每个姓氏下的名字,每个姓氏下都有十页,但是发现并不是每一页都是存在姓名的。
  • 最后进每一个姓氏的详细页面,爬取每个姓名的相同人数和五行和三才。

工作环境和爬取的框架: python3 scrapy

爬取数据量: 姓氏435个 姓名194万数据

代码

1 准备工作

新建scrapy项目 和新建爬虫项目(2个)

scrapy startproject baijiaxing1
scrapy genspider baijiaxing2 resgain.net/xmdq.html
scrapy genspider spider_xingming resgain.net/xmdq.html

解释下为什么要创建两个爬虫项目

因为scrapy是多线程的爬取方式,我之前写在一起,会同时爬取姓氏和姓名,但是姓名中有一个字段是姓氏的id,这样就会存在一个情况 姓名抓取都的时候姓氏还没有存到数据库中,会导致报错。但想一想,应该有其他办法可以解决这个问题,本人也是才接触scrapy,所以采用这种笨方法。

baijiaxing2 是爬取姓氏, spider_xingming 是爬取姓名

2 建立items

Items.py

# -*- coding: utf-8 -*-

import scrapy


class Xingshi_Item(scrapy.Item):
    xingshi = scrapy.Field()
    href = scrapy.Field()
    xingshi_zhongwen = scrapy.Field()


class Xingming_Item(scrapy.Item):
    name = scrapy.Field()
    the_same_people_number = scrapy.Field()
    boy_ratio = scrapy.Field()
    girl_ratio = scrapy.Field()
    five_elements = scrapy.Field()
    three_talents = scrapy.Field()
    xingshi = scrapy.Field()

3 爬取所有姓氏

# -*- coding: utf-8 -*-
import scrapy

from baijiaxing1.items import Xingshi_Item


class Baijiaxing2Spider(scrapy.Spider):
    name = 'baijiaxing2'
    # allowed_domains = ['resgain.net/xmdq.html']
    start_urls = ('http://www.resgain.net/xmdq.html',)

    def parse(self, response):
        content = response.xpath('//div[@class="col-xs-12"]/a')

        for i in content:
            # xingshi = i.split('.')[0].split('/')[-1]
            xingshi = i.xpath('./@href').extract()[0].split('.')[0].split('/')[-1]

            href = 'http:' + i.xpath('./@href').extract()[0]
            item = Xingshi_Item()
            item['xingshi'] = xingshi
            item['href'] = href
            item['xingshi_zhongwen'] = i.xpath('./text()').extract()[0].split('姓名')[0]

            yield item

4 爬取所有名字

# -*- coding: utf-8 -*-
from urllib.parse import urljoin

import scrapy

from baijiaxing1.items import Xingshi_Item, Xingming_Item


class SpiderXingmingSpider(scrapy.Spider):
    name = 'spider_xingming'
    # allowed_domains = ['www.resgain.net/xmdq.html']
    start_urls = ('http://www.resgain.net/xmdq.html',)

    def parse(self, response):
        content = response.xpath('//div[@class="col-xs-12"]/a/@href').extract()

        for i in content:
            page = 0
            href = 'http:' + i
            base = href.split('/name')[0] + '/name_list_'
            while page < 10:
                url = base + str(page) + '.html'
                page += 1
                yield scrapy.Request(url, callback=self.parse_in_html)

    # 解析每一页
    def parse_in_html(self, response):
        person_info = response.xpath('//div[@class="col-xs-12"]/a')
        base_url = 'http://'+response.url.split('/')[2]
        xingshi = response.url.split('/')[2].split('.')[0]
        for every_one in person_info:
            name = every_one.xpath('./text()').extract()[0]
            href = every_one.xpath('./@href').extract()[0]
            the_person_info_url =base_url + href
            the_item = Xingming_Item()
            the_item['name'] = name
            the_item['xingshi'] = xingshi
            yield scrapy.Request(the_person_info_url, meta={'the_item': the_item}, callback=self.parse_every_html)


    def parse_every_html(self, response):
        the_item = response.meta['the_item']
        the_same_people_number = \
        response.xpath('//div[@class="navbar-brand"]/text()').extract_first().split('人')[0].split('有')[1]
        boy_ratio = \
        response.xpath('//div[@class="progress"]/div[contains(@class,progress-bar)]/text()').extract()[0].split('情况')[0]
        girl_ratio = \
        response.xpath('//div[@class="progress"]/div[contains(@class,progress-bar)]/text()').extract()[1].split('情况')[0]
        five_elements = response.xpath('//div[@class="panel-body"]/div[@class="col-xs-6"]/blockquote/text()').extract()[
            0]
        three_talents = response.xpath('//div[@class="panel-body"]/div[@class="col-xs-6"]/blockquote/text()').extract()[
            1]
        the_item['the_same_people_number'] = the_same_people_number,
        the_item['boy_ratio'] = boy_ratio,
        the_item['girl_ratio'] = girl_ratio,
        the_item['five_elements'] = five_elements,
        the_item['three_talents'] = three_talents

        yield the_item

5 pipelines.py

# -*- coding: utf-8 -*-

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html
import pymysql

from baijiaxing1.items import Xingshi_Item, Xingming_Item


class XingShiPipeline(object):
    def __init__(self,host, database, user, password, port):
        self.host = host
        self.database = database
        self.user = user
        self.password = password
        self.port = port

    def process_item(self, item, spider):
        if isinstance(item, Xingshi_Item):
            sql = 'INSERT INTO baijiaxing(xingshi,href,xingshi_zhongwen) VALUES (%s,%s,%s);'
            self.cursor.execute(sql,(item['xingshi'],str(item['href']),item['xingshi_zhongwen']))
            self.db.commit()
            return item
        elif isinstance(item,Xingming_Item):
            sql = 'SELECT id FROM xingshi WHERE xingshi = %s' %item['xingshi']
            xingshi_id = self.cursor.execute(sql)
            sql = 'INSERT INTO xingming(name,the_same_people_number,boy_ratio,girl_ratio,five_elements,three_talents,xingshi_id)values (%s,%s,%s,%s,%s,%s,%s);'
            self.cursor.execute(sql,(item['name'],item['the_same_people_number'][0],item['boy_ratio'][0],item['girl_ratio'][0],item['five_elements'][0],item['three_talents'],int(xingshi_id)))
            self.db.commit()
            return item

    @classmethod
    def from_crawler(cls, crawler):
        return cls(
            host=crawler.settings.get('PYMYSQL_HOST'),
            database=crawler.settings.get('PYMYSQL_DATABASE'),
            user=crawler.settings.get('PYMYSQL_USER'),
            password=crawler.settings.get('PYMYSQL_PASSWORD'),
            port=crawler.settings.get('PYMYSQL_PORT'),
        )

    def open_spider(self, spider):
        self.db = pymysql.connect(self.host, self.user, self.password, self.database, port=self.port)
        self.cursor = self.db.cursor()

    def close_spider(self, spider):
        self.db.close()


因为有两个item,所以在process_item中要区分是哪个item返回的数据。

6 settings.py

最后在settings.py中设置数据库的配置以及请求头的配置

USER_AGENT = 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; 360SE)'
ROBOTSTXT_OBEY = False
# mysql数据库设置
PYMYSQL_HOST = '127.0.0.1'
PYMYSQL_DATABASE = 'test1'
PYMYSQL_USER = 'root'
PYMYSQL_PASSWORD = '123456'
PYMYSQL_PORT = 3306

7 数据库表

Baijiaxing 表

id xingshi href xingshi_zhongwen

xingming表

id name the_same_people_number boy_ratio girl_ratio five_elements three_talents xingshi_id

8 开始

因为有两个spiders,而且是先运行baijiaxing1 后运行spider_xingming 所以写了一个run.py文件

run.py

import os
os.system("scrapy crawl baijiaxing2")
os.system("scrapy crawl spider_xingming")

github地址:https://github.com/Fizzyi/baijiaxing/tree/master

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