scrapy框架爬虫的简单学习

scrapy框架爬虫的简单学习


最近接触到不少爬虫的信息,不是主动的,是被动的,关于爬虫的文章多了起来,在村里网吧上网经常会看到,所以被动的了解了一些。
可能是python变得热门的表现吧,所以我决定也学学爬虫,下面是我学习scrapy框架时写的,爬取世纪佳缘的20到28岁女用户的一些数据。
you:“那么为什么不爬男用户”;i:“好问题,如果我爬了男用户,你或许又会问,那为什么不爬女用户,它总的有一种性别吧”;you:“狡辩,不就是喜欢美女吗”

爬虫的工作很简单,主要分两部分,请求数据,得到数据后解析,如果有下一个数据,比如下一页,或下级链接,那么可以拿到这些链接,继续爬取。
以世纪佳缘网为例,网站有一个搜索用户的页面,打开这种搜索页,网页展示了25个用户信息,在浏览器中,每次点击下一页都会得到一个xhr数据,打开它正是用户的信息,我们直接请求这个数据就好了

下面是开始请求代码:设置请求数据,提交请求,指定callback回调函数,数据将在这个数据中返回

def start_requests(self):
        index = str(self.current_index)
        data = {
                'sex': 'f',
                'key': '',
                # select condition选择条件
                'stc': '2:20.27,28:0,23:1',
                'sn': 'charm',
                'sv': '1',
                # ‘p’ 字段是当前的页数
                'p': index,
                'f': 'select',
                'listStyle': 'bigPhoto',
                'pri_uid': '100999311',
                'jsversion': 'v5'
            }
        return [scrapy.FormRequest(url="http://search.jiayuan.com/v2/search_v2.php",
                                   method="POST",
                                   headers=self.my_header,
                                   formdata=data,
                                   meta={"cookiejar": 1},
                                   callback=self.logged_in)]

下面是回调函数,解析返回的数据

def logged_in(self, response):
        json_str = response.text
        # 因为json数据的头部和加了'##jiayser##'这几个字符,去掉它
        split = re.split(r'##jiayser##', json_str)
        json_str=split[1]
        dict_json = json.loads(json_str) 
        # 解析
        for user in dict_json['userInfo']:
            userItem = TestprojectItem()
            userItem['uid'] = user['realUid']
            userItem['nickname'] = user['nickname']
            userItem['sexValue'] = user['sexValue']
            userItem['marriage'] = user['marriage']
            userItem['height'] = user['height']
            userItem['education'] = user['education']
            userItem['work_location'] = user['work_location']
            userItem['age'] = user['age']
            userItem['shortnote'] = user['shortnote']
            yield userItem

如果要爬取下一页,只需将请求头中的 ‘p’(page)增加1,得到再继续爬取即可
存在问题,当爬取1000条数据以后,再爬取的数据,都是前面已经爬到的,应该是网站发爬虫的原因,求大神指点

以下为spider部分的完整代码
import random
import re
from time import sleep
import requests

import scrapy
import json
from scrapy.http.cookies import CookieJar

from testproject.items import TestprojectItem


class TestSpiderSpider(scrapy.Spider):
    name = 'test_spider'
    allowed_domains = ['jiayuan.com']
    start_urls = ['http://search.jiayuan.com/v2/search_v2.php']


    current_index = 1
    my_header = {'X-Requested-With': 'XMLHttpRequest',
                 'Host': 'search.jiayuan.com',
                 'Origin': 'http://search.jiayuan.com',
                 'Referer': 'http://search.jiayuan.com/v2/',
                 'Accept': '*/*',
                'Accept-Encoding':'gzip, deflate',
                'Accept-Language':'zh-CN,zh;q=0.9',
                'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
                 }

    def start_requests(self):
        index = str(self.current_index)
        data = {
                'sex': 'f',
                'key': '',
                # select condition选择条件
                'stc': '2:20.27,28:0,23:1',
                'sn': 'charm',
                'sv': '1',
                # ‘p’ 字段是当前的页数
                'p': index,
                'f': 'select',
                'listStyle': 'bigPhoto',
                'pri_uid': '100999311',
                'jsversion': 'v5'
            }
        return [scrapy.FormRequest(url="http://search.jiayuan.com/v2/search_v2.php",
                                   method="POST",
                                   headers=self.my_header,
                                   formdata=data,
                                   meta={"cookiejar": 1},
                                   callback=self.logged_in)]

    #解析函数   
    def logged_in(self, response):
        json_str = response.text
        # 因为json数据的头部和加了'##jiayser##'这几个字符,去掉它
        split = re.split(r'##jiayser##', json_str)
        json_str=split[1]
        dict_json = json.loads(json_str) 
        # 解析
        for user in dict_json['userInfo']:
            userItem = TestprojectItem()
            userItem['uid'] = user['realUid']
            userItem['nickname'] = user['nickname']
            userItem['sexValue'] = user['sexValue']
            userItem['marriage'] = user['marriage']
            userItem['height'] = user['height']
            userItem['education'] = user['education']
            userItem['work_location'] = user['work_location']
            userItem['age'] = user['age']
            userItem['shortnote'] = user['shortnote']
            yield userItem
        # 解析之后,如果当前页小于100,继续抓取
        if self.current_index < 100:
            self.current_index = self.current_index+1       # 下一页
            index = str(self.current_index)
            # 设置请求提交数据
            data = {
                'sex': 'f',
                'key': '',
                # select condition选择条件,'1'是省份,'2'是年龄范围,在浏览器中提交一个请求后可以看到
                'stc': '1:46,2:20.29',
                'sn': 'default',
                'sv': '1',
                'p': index,
                'f': 'select',
                'listStyle': 'bigPhoto',
                'pri_uid': '1',
                'jsversion': 'v5'
            }

            response_cookie = response.headers.getlist('Set-Cookie')

            # 随机暂停
            sleep(random.uniform(1,10))

            yield scrapy.FormRequest(url="http://search.jiayuan.com/v2/search_v2.php",
                                   method="POST",
                                   headers=self.my_header,
                                   formdata=data,
                                   callback=self.logged_in,
                                   meta = {"cookiejar": response.meta['cookiejar']} )


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值