用scrapy框架写爬虫

结构图

爬虫可以发送给引擎的两种请求:

    # 1、url:
    # (爬虫)yield scrapy.Request -> 引擎 -> 调度器(发送给调度器入队) -> 引擎(调度器出队请求于引擎)
    # -> 下载器(引擎发送于下载器) -> 引擎(下载器成功(失败)返回引擎):-> 爬虫(引擎接收成功将给爬虫response)or -> 调度器(失败给调度器重新下载)
    # -> 引擎(爬虫接收response并做处理,发送跟进url:yield scrapy.Request) -> 调度器(引擎发送给调度器入队) ->...
    # 2、weiboitem:
    # 一般在接收response后便有了数据,然后
    # (爬虫) yield weiboitem -> 引擎 -> pipelines(管道)进行存储,管道中自己写存储代码 -> mysql or redis

一、准备工作

  • python、pip、scrapy(pip install Scrapy)
  • 测试:scrapy fetch http://www.baidu.com

二、构建crapy框架

  • 创建爬虫项目(cmd或terminal):scrapy startproject mySpiderName
  • cd:cd mySpider
  • 创建爬虫:scrapy genspider myspidername www.dytt8.net
    ( www.dytt8.net 是要爬取网址的根域名,只有在此根域名才能爬取到内容)
  • 修改settings协议: ROBOTSTXT_OBEY = False
  • 切记在settings中ITEM_PIPELINES列表添加语句(打开注释),否则管道不会被执行:
    ‘mySpiderName.pipelines.WeiboSpiderPipeline’: 300,

三、填写代码三部曲

  • 在自动生成的spiders文件夹下的myspider.py文件中编辑:
import scrapy
from hotnewsSpider.items import WeiboSpiderItem     # hotnewsSpider为项目名,WeiboSpiderItem为爬虫item类,在items.py中可找到
                                                    # 创建第二个爬虫时需要手动在items中添加此类

from bs4 import BeautifulSoup

class WeiboSpider(scrapy.Spider):
	# 以微博为例:
 	name = 'weibo'                          # 爬虫名 -- 自动生成,唯一,不可变
    allowed_domains = ['s.weibo.com']       # 允许访问的根域名
    start_urls = ['http://s.weibo.com/']    # 起始访问地址
    
    searchName = "张钧甯 感谢抬爱"
    headers = {

    }
    cookies = {

    }
    urls = [
        # 模拟搜索 searchName
        "https://s.weibo.com/weibo?q=%s&Refer=SWeibo_box"%searchName

    ]
    # urls.extend(start_urls)

	# 重写起始请求,可以给请求加上许多信息
    def start_requests(self):
        # 发送初始请求
        for url in self.urls:
            yield scrapy.Request(url=url, headers=self.headers, cookies=self.cookies, callback=self.parse)

    # 默认第一次返回response接收函数,第二次response可以继续返回这里,也可以返回你定义的人一个函数中,
    # 这在yield scrapy.Request(url,callback=self.your_parse)中决定
    def parse(self, response):
    
        # 用爬虫对应的item类声明一个对象,类型为字典,用来保存数据,通过 yield weiboitem 返回给引擎
        weiboitem = WeiboSpiderItem()                       # from hotnewsSpider.items import WeiboSpiderItem
		
		# BeautifulSoup代码块:
        html = response.text
        soup = BeautifulSoup(html, 'lxml')
        content_id_div = soup.find(id='pl_feedlist_index')
        card_wraps = content_id_div.find_all(class_='card-wrap')

        id = 0

        for card_wrap_item in card_wraps:
            # 用户名
            username = card_wrap_item.find(class_='info').find(class_='name').text

            # 用户头像
            user_headimg = card_wrap_item.find(class_='avator').find('img')['src']

            # 内容
            # 文字 偶尔会搜索出某个人
            content_text_html = card_wrap_item.find(class_='txt')
            content_text = ''
            if content_text_html:
                content_text = content_text_html.get_text().replace(' ', '').replace('\n', '').replace('展开全文c', '')

            # 图片 有的无图
            img_items_html = card_wrap_item.find(class_='m3')
            content_imgs = []
            if img_items_html:
                for img_item in img_items_html.find_all('img'):
                    content_imgs.append(img_item['src'])

            # (收藏)、转发、评论、点赞数量
            other_items_html = card_wrap_item.find(class_='card-act')
            other_items_dic = {}
            if other_items_html:
                other_items_lst = other_items_html.find_all('a')
                for other_item_index in range(len(other_items_lst)):
                    if other_item_index == 0:
                        other_items_dic['收藏'] = ""
                    elif other_item_index == 1:
                        other_items_dic['转发'] = other_items_lst[other_item_index].text.strip().split()[1]
                    elif other_item_index == 2:
                        other_items_dic['评论'] = other_items_lst[other_item_index].text.strip().split()[1]
                    else:
                        other_items_dic['点赞'] = other_items_lst[other_item_index].text.strip()
            # print(other_items_dic)
            id += 1
            weiboitem['id'] = id
            weiboitem['username'] = username
            weiboitem['user_headimg'] = user_headimg
            weiboitem['content_text'] = content_text
            weiboitem['content_imgs'] = content_imgs
            weiboitem['other_items_dic'] = other_items_dic

            yield weiboitem		# 返回数据给引擎,引擎将其传入管道执行管道中的代码
            # yield scrapy.Request(url,callback=self.parse)	# 返回跟进url给引擎
            # yield scrapy.Request(url,callback=self.parse2)	# 返回跟进url给引擎

            break       # 用于测试,只拿一次数据
          
 	def parse2(self,response):
 		pass
  • 在items.py中初始化item字典(第二次以上新建的爬虫需要自己新增对应类)
import scrapy


# 第一个爬虫对应的item类,在创建项目时自动产生
class HotnewsspiderItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    pass

# 自己新增的爬虫类
class WeiboSpiderItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    id = scrapy.Field()
    username = scrapy.Field()
    user_headimg = scrapy.Field()
    content_text = scrapy.Field()
    content_imgs = scrapy.Field()
    other_items_dic = scrapy.Field()
    pass
  • 在pipelines.py中保存数据
# 第一个爬虫对应的Pipeline类,在创建项目时自动产生
class HotnewsspiderPipeline(object):
    def process_item(self, item, spider):
        pass
        # return item

# 自己新增的爬虫类
# 切记在settings中ITEM_PIPELINES列表添加语句,否则不会被执行:
# 'hotnewsSpider.pipelines.WeiboSpiderPipeline': 300,
class WeiboSpiderPipeline(object):
    def process_item(self, item, spider):
        # 在这里将数据存入mysql,redis
        print(item)

运行:

  • scrapy crawl mysipdername(别忘了cd目录)
  • 添加以下任意一个py运行文件命名run或main,要与scrapy.cfg文件同级目录
    更改自己的爬虫名即可右键运行
一、
from scrapy.cmdline import execute
import sys
import os

'''
运行scrapy爬虫的方式是在命令行输入    scrapy crawl <spider_name>
调试的常用方式是在命令行输入          scrapy shell <url_name>
'''

sys.path.append(os.path.dirname(os.path.abspath(__file__)))

execute(['scrapy', 'crawl', 'weibo'])  # 你需要将此处的spider_name替换为你自己的爬虫名称
二、
from scrapy.crawler import CrawlerProcess
from scrapy.utils.project import get_project_settings

'''
运行scrapy爬虫的方式是在命令行输入    scrapy crawl <spider_name>
调试的常用方式是在命令行输入          scrapy shell <url_name>
'''

if __name__ == '__main__':
    process = CrawlerProcess(get_project_settings())
    process.crawl('weibo')    #  你需要将此处的spider_name替换为你自己的爬虫名称
    process.start()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值