booking爬取之反扒斗争

本文介绍了一个针对Booking(缤客)网站的爬虫实现,重点讨论了如何应对反扒机制,包括全局配置、数据库连接池、cookie重写策略。代码中存在关键参数用于获取城市ID,通过线程控制多城市爬取,并从列表页和详情页抓取酒店数据。同时,文章指出代码存在冗余,特别是SQL部分,期望得到优化建议。由于业务需求,代码需要进一步扩展以支持国内外不同方案的数据获取,以及中英文城市名称的爬取。
摘要由CSDN通过智能技术生成

本篇文章为booking(缤客)爬取,公司工作所用部分关键将打码

全局化配置:

from DBUtils.PooledDB import PooledDB###sql连接池
from requests.cookies import RequestsCookieJar#保存cookie
import requests
import re
import time
import datetime
import random
import json
import pymysql
from lxml import etree
import threading

b = {"user": "******",
     "passwd": "********",
     "host": "*******",
     "db": 'price',
     "port": 3306,
     "charset": 'utf8'
     }
h=0
cookie_jar=""
cookie_jar1=""

类的初始化配置:

class Booking(threading.Thread):
    __pool = None
    _instance_lock = threading.Lock()

    def __init__(self,threadID, name, counter):
        #线程的id,名称等,需要查看的可以用用,此处未用到
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.counter = counter
        #生成时间
        # self.Innew = (datetime.datetime.now()+datetime.timedelta(days=1)).strftime('%Y-%m-%d')
        # self.Outnew = (datetime.datetime.now()+datetime.timedelta(days=10)).strftime("%Y-%m-%d")
        #用上面的时间比较好我这里是由特殊需求
        self.Innew="2018-10-20"
        self.Outnew="2018-10-31"
        # 将数据库连接游标初始化
        #数据库部分一定不能这么写否则就是共享一个连接了
        #self.coon = Booking.getmysqlconn()
        #self.cur = self.coon.cursor(cursor=pymysql.cursors.DictCursor)

数据库配置:

# sql连接池
    @staticmethod
    def getmysqlconn():
        if Booking.__pool is None:
            __pool = PooledDB(creator=pymysql, mincached=3, maxcached=20, host=b["host"], user=b["user"],
                              passwd=b["passwd"], db=b["db"], port=b["port"], charset=b["charset"])
        return __pool.connection()

    # 插入\更新\删除sql\
        def op_insert(self, sql='',value=(),insert_statue=1,_id=None):
        """
        实现数据库insert/update/delete
        :param _id就是在只插入一个的情况下返回一个id并改变_id值,不用传值默认None,
        :param insert_statue: 插入状态int值,1为单词插入一个,2为插入多个值,三或以上为删除或修改模式,默认为1
        :param sql: 插入的sql格式
        :param value: 当插入一个值时为tuple/list,多个值时为tuple(tuple)/list[list],非插入状态下value可为()
        :return:
        """
        my_coon = Sql_all.getmysqlconn()
        my_cur = my_coon.cursor(cursor=pymysql.cursors.DictCursor)
        try:
            print('op_insert',sql)
            if insert_statue==1:
                my_cur.execute(sql,value)
                _id = my_cur.lastrowid#获取插入的id
            elif insert_statue==2:
                my_cur.executemany(sql,value)
            else:
                my_cur.execute(sql, value)
            print("修改中")
            my_coon.commit()
            print("修改成功")
            self.dispose(my_coon,my_cur)
            if _id == 0:
                return True
            return True,_id
        except Exception as e:
            print(e)
            my_coon.rollback()
            self.dispose(my_coon,my_cur)
            print("修改失败请检查sql语句")
            return 0

    # 查询
        def mysql_select(self,sql='',select_satue=2,num=None,param=None):
        """
        实现MySQL数据库取的功能
        :param sql:sql查询语句如有体条件,把条件传入param
        :param param:可选参数,条件列表值(元祖/列表),默认None
        :param num:当只需要查询一部分时候,默认None
        :param select_satue,可选状态int类型(或能被转成int得值),1为查询一条,2为查询所有,
                3或其他为查询一部分(三种状态都是在指定条件下返回的数量)此时需传入参数num,默认2查询所有
        :return:
        """
        my_coon = Sql_all.getmysqlconn()
        my_cur = my_coon.cursor(cursor=pymysql.cursors.DictCursor)
        try:
            if param == None:
                count=int(my_cur.execute(sql))  # 执行sql
            else:
                count =int(my_cur.execute(sql,param))
            # print(count)
            if count >0:
                # print(count)
                if int(select_satue)==2:
                    select_res = my_cur.fetchall()# 返回结果为字典
                elif int(select_satue)==1:
                    select_res=my_cur.fetchone()
                else:
                    select_res=my_cur.fetchmany(num)
            else:
                #此处了在代码的查寻结果一定要判断否则汇报bool类型问题
                select_res=False

      
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值