从抓取Tencent中学习Scrapy

一.创建爬虫工程

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 引擎和调度器将负责到底。
原文地址:https://www.cnblogs.com/hhy-love-python/p/8514907.html