条件爬取Flash网站数据,百度都是不带条件的爬取_志伟爬虫_第二篇

很久很久没写博客了,可能最近半年太懒了,也可能是工作忙,忙的打王者,忙的打游戏,没空写博客,哈哈哈,由于不写博客,很久没妹纸找我问东西了,哈哈,还是动手写写吧,不废话直接开始了

之前学了一周爬虫,写了一个爬虫(经理要求写,没办法,那就学学呗),但是当时没写博客,当时忘记了,很基础的爬取了十万条数据,然后插入数据库,当时遇到很多难题,等有空了总结下吧

经理昨天让我写爬虫,我一心想着之前写过啊,直接根据页面标签拿下来不就完事了,顶多一小时的事,结果看了需求才知道,爬取的flash页面,不存在标签,好吧,那就老规矩百度呗,
这是百度到的爬取Flash网站代码地址
上代码


# coding: utf-8
# agri.gov.cn_amf_client.py
# http://jgsb.agri.gov.cn/flexapps/hqApp.swf数据抓取

# http://jgsb.agri.cn/controller?SERVICE_ID=REGISTRY_JCSJ_MRHQ_SHOW_SERVICE&recordperpage=15&newsearch=true&login_result_sign=nologin

import urllib
import urllib2
from urllib2 import Request
import uuid
import pyamf
import json,datetime
from pyamf import remoting
from pyamf.flex import messaging
class HqPara:
    def __init__(self):
        self.marketInfo = None
        self.breedInfoDl = None
        self.breedInfo = None
        self.provice = None
# registerClassAlias("personTypeAlias", Person);
# 注册自定义的Body参数类型,这样数据类型com.itown.kas.pfsc.report.po.HqPara就会在后面被一并发给服务端(否则服务端就可能返回参数不是预期的异常Client.Message.Deserialize.InvalidType)
pyamf.register_class(HqPara, alias='com.itown.kas.pfsc.report.po.HqPara')
# 构造flex.messaging.messages.RemotingMessage消息
msg = messaging.RemotingMessage(messageId=str(uuid.uuid1()).upper(),
                                    clientId=str(uuid.uuid1()).upper(),
                                    operation='getHqSearchData',
                                    destination='reportStatService',
                                    timeToLive=0,
                                    timestamp=0)
# 第一个是查询参数,第二个是页数,第三个是控制每页显示的数量(默认每页只显示15条)但爬取的时候可以一下子设置成全部的数量
# 构造请求数据
def getRequestData(page_num,total_num):
    msg.body = [HqPara(),str(page_num), str(total_num)]
    msg.headers['DSEndpoint'] = None
    msg.headers['DSId'] = str(uuid.uuid1()).upper()
    # 按AMF协议编码数据
    req = remoting.Request('null', body=(msg,))
    env = remoting.Envelope(amfVersion=pyamf.AMF3)
    env.bodies = [('/1', req)]
    data = bytes(remoting.encode(env).read())
    return data
# 返回一个请求的数据格式

def getResponse(data):
    url = 'http://jgsb.agri.cn/messagebroker/amf'
    req = Request(url, data, headers={'Content-Type': 'application/x-amf'})
    # 解析返回数据
    opener = urllib2.build_opener()
    return opener.open(req).read()


def getContent(response):
    amf_parse_info = remoting.decode(response)
    # 数据总条数
    total_num = amf_parse_info.bodies[0][1].body.body[3]
    info = amf_parse_info.bodies[0][1].body.body[0]
    print info
    return total_num, info

def store2json(info):
    res = []
    for record in info:

        record['reportDate'] = record['reportDate'].strftime('%Y-%m-%d %H:%M:%S')
        record['auditDate'] = record['auditDate'].strftime('%Y-%m-%d %H:%M:%S')
        res.append(record)
    fp = open('info.json','w')
    json.dump(res,fp,indent=4)
    fp.close()




# 获取数据量
reqData = getRequestData(1,2)
rep = getResponse(reqData)
total_num,info = getContent(rep)
# 一次请求完成
reqData = getRequestData(1,total_num)
rep = getResponse(reqData)
total_num,info = getContent(rep)
print info
for record in info:
    print record

store2json(info)

这里用到了抓包工具Charles,之前用过抓包工具Flidder,但是抓不打amf文件,我测试了跟浏览器显示的数据一样都是乱码,然后才用的Charles,这款工具很强大,但是下载很慢,给你们一个我自己的百度网盘吧,我可是下载了1小时才下载到的,且行且珍惜,具体怎么用就不给你们BB了,不会用的话,去百度

这是4.2版本;因为我抓包过程中4.5突然不好使了,就下载的4.2,能用4.5,就用4.5吧,最新的比较好

4.2版本
链接:4.2版本Charles
提取码:eb1b

4.5版本

链接:4.5版本Charles
提取码:sijk

基本上按照百度上那个链接进行操作把你的Python引入一下包,改改配置,基本就可以跑起来程序,跑起来是抓取的全部的信息

在这里插入图片描述图片中的content就是请求内容和响应内容,请求内容Body里面就是需要传的值,具体怎么传请求参数的话,就是难点了,Python大佬勿喷,我学Java的,不擅长Python,所以可能感觉难,结合下面的代码来看,查询条件不就是四个吗,直接传就行了,我一开始也是这么想的,但是那样改的话程序爬不起来,一直报错,不存在该类型什么的

在这里插入图片描述上图我圈起来的也看到了,传的参数不是一个字符串String类型的,所以直接改成字符串就会报错,所以必须创建这四个类来进行传参,这是正常思考的逻辑吧?因此我开始建了四个类,废话不多说,直接上代码

class BreedInfoPo():

    def init(self, children0, item_code, item_name, children1):
        self.parentcode = None
        self._children = children0
        self.itemcode = item_code  # String 000000
        self.itemname = item_name  # String 全部
        self.children = children1

class ProvincePo():

    def init(self, item_code, item_name):
        self._children = None
        self.itemcode = item_code  # String 000000
        self.itemname = item_name  # String 全国
        self.children = None

class BreedInfo():

    def init(self, item_code, item_name):
        self.parentcode = None
        self._children = None
        self.itemcode = item_code  # String AM
        self.itemname = item_name  # String 水产品
        self.children = None

class PMarketInfo():

    def  init(self, market_code, market_name):
        self.marketCode = market_code
        self.marketName = market_name  # String 000000/AM

创建完这四个类,就可以写个方法进行传参,这里创建四个类的时候遇到一个坑,对于这段代码,Python解释器报错:object() takes no parameters
这个问题没啥说的百度就知道,少下划线的问题,init初始化必须添加两遍下划线的,加上去就行了,然后继续写方法

def construct_request(product_code, product_name, provice_code, provice_name, breed_code, breed_name, market_code, market_name, page_num, total_num):
    breedInfo = BreedInfoPo(None, product_code, product_name, None)
    provice = ProvincePo(provice_code, provice_name)
    breedInfoDl = BreedInfo(breed_code, breed_name)
    marketInfo = PMarketInfo(market_code, market_name)

这一步就是传参初始化,基本没啥技术含量,写个方法而已

然后你又跑程序,发现又报错,说什么不存在class什么的,看看代码,你会发现有一段代码是注册自定义的body

# registerClassAlias("personTypeAlias", Person);
# 注册自定义的Body参数类型,这样数据类型com.itown.kas.pfsc.report.po.HqPara就会在后面被一并发给服务端(否则服务端就可能返回参数不是预期的异常Client.Message.Deserialize.InvalidType)
pyamf.register_class(HqPara, alias='com.itown.kas.pfsc.report.po.HqPara')

好吧,只要需要穿的body实体类,都需要先注册一下,那就根据类型来注册一下啊

pyamf.register_class(BreedInfoPo, alias='com.itown.kas.pfsc.report.po.BreedInfoPo')
pyamf.register_class(ProvincePo, alias='com.itown.kas.pfsc.report.po.ProvincePo')
pyamf.register_class(BreedInfo, alias='com.itown.kas.pfsc.report.po.BreedInfoPo')
pyamf.register_class(PMarketInfo, alias='com.itown.kas.pfsc.report.po.PMarketInfo')

注册以后基本就没报错了,如果还报错,就慢慢找,基本都是小问题了,flash传参问题解决其他都不是问题了,恩,来调用方法试试我们写好的代码

在这里插入图片描述在这里插入图片描述哎呦,没有查询全国的7000多条数据了,查到了指定的36条数据,看看网站是不是36条数据呢?

在这里插入图片描述哈哈哈,网站上的36条数据都拿到了,然后就是存数据库,展示数据,那些都是第一次写爬虫遇到的问题以后再写,都快忘记了,改天补上吧,存库的时候一次存一条,那即使淘宝的数据库存10万次数据库,我感觉也够呛,那些坑都过去了,哈哈哈

发布了12 篇原创文章 · 获赞 1 · 访问量 8152

猜你喜欢

转载自blog.csdn.net/Jaeger_Java/article/details/103679813