一.创建爬虫工程
scrapy startproject MyScrapy
二.创建爬虫
scrapy genspider tencetn tencent.com
三.明确需要爬取的内容(各种存储,方便可持续化用)
1.打开MySpider目录下的item.py
2.Item定义结构化数据,用来保存爬取到的数据,类似字典
3.创建TencentItem类
class TencentItem(scrapy.Item): name=scrapy.Field() detailLink=scrapy.Field() category=scrapy.Field() number=scrapy.Field() worklocation=scrapy.Field() publishData=scrapy.Field()
四.设置爬虫初始url,解析数据获取想要的内容和生成爬虫过程中另外生成的url
import scrapy from ..items import TencentItem from bs4 import BeautifulSoup class TencentSpider(scrapy.Spider): name = 'tencent' # allowed_domains = ['tencent.com'] start_urls = ['https://hr.tencent.com/position.php?&start=10#a'] def parse(self, response): r=response.body.decode('utf-8') html = BeautifulSoup(r, 'lxml') result = html.select('tr[class="even"]') result2 = html.select('tr[class="odd"]') result += result2 item=TencentItem() for site in result: name = site.select('td a')[0].get_text() detailLink = site.select('td a')[0].attrs.get('href') category = site.select('td')[1].get_text() number = site.select('td')[2].get_text() worklocation = site.select('td')[3].get_text() publishData = site.select('td')[4].get_text() item['name'] = name item['detailLink'] = detailLink item['category'] = category item['number'] = number item['worklocation'] = worklocation item['publishData'] = publishData yield item
五.做数据持久化
可以使用终端命令保存信息,-o指定格式的文件,这是需要注意编码问题
在setting.py文件中添加以下代码解决中文乱码问题
FEED_EXPORT_ENCODING = 'utf-8'
#json格式 scrapy crawl tencent -o tencent.json #csv格式 scrapy crawl tencent -o tencent.csv #xml格式 scrapy crawl tencent -o tencent.xml #jsonl格式 scrapy crawl tencent -o tencent.jsonl
也可以在ItemPipe中保存信息
class TencentPipeline(object): #做参数初始化 def __init__(self): self.file=open('tencent.json','w',encoding='utf-8') #必须实现 def process_item(self,item,spider): content=json.dumps(dict(item),ensure_ascii=False)+' ' self.file.write(content) return item #当spider被关闭时,这个方法被调用 def close_spider(self,spider): self.file.close()
现在,我们来梳理一下整个项目的流程
1. 因为使⽤的 yield,⽽不是 return。parse 函数将会被当做⼀个⽣成器使⽤。sc rapy 会逐⼀获取 parse⽅法中⽣成的结果,并判断该结果是⼀个什么样的类型; 2. 如果是 request 则加⼊爬取队列,如果是 item 类型则使⽤pipeline 处理,其他 类型则返回错误信息。 3. scrapy 取到第⼀部分的 request 不会⽴⻢就去发送这个 request,只是把这个 re quest 放到队列⾥,然后接着从⽣成器⾥获取; 4. 取尽第⼀部分的 request,然后再获取第⼆部分的 item,取到 item 了,就会放 到 对应的 pipeline⾥处理; 5. parse()⽅法作为回调函数(callback)赋值给了 Request,指定 parse()⽅法 来 处理这些请求 scrapy.Request(url, callback=self.parse) 6. Request 对象经过调度,执⾏⽣成 scrapy.http.response()的响应对象, 并 送回给 parse()⽅法,直到调度器中没有 Request(递归的思路) 7. 取尽之后,parse()⼯作结束,引擎再根据队列和 pipelines 中的内容去执⾏相 应的操作; 8. 程序在取得各个⻚⾯的 items 前,会先处理完之前所有的 request 队列⾥的请求 ,然后再提取 items。 7. 这⼀切的⼀切, Scrapy 引擎和调度器将负责到底。