爬虫可以发送给引擎的两种请求:
# 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 BeautifulSoupclass 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.textsoup = BeautifulSoup(html, 'lxml')content_id_div = soup.find(id='pl_feedlist_index')card_wraps = content_id_div.find_all(class_='card-wrap')id = 0for 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 += 1weiboitem['id'] = idweiboitem['username'] = usernameweiboitem['user_headimg'] = user_headimgweiboitem['content_text'] = content_textweiboitem['content_imgs'] = content_imgsweiboitem['other_items_dic'] = other_items_dicyield 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,redisprint(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()