python爬虫(网页端,app端)

不知不觉间爬虫的任务越来越多了,我都开始怀疑是不是当时写简历的时候手一抖,面成了爬虫工程师。

1. 简介

也没有用到什么高深的东西,ip有限,带宽有限,大多都是挂个代理单进程单线程,偶尔用到多线程。
主要也就是记录一下成长历程,思路什么的简单来说就是让你的程序看起来像个人

2. 网页端

很多网站可能都设置了各种各样的陷阱来判断你是人还是机器,我们这边其实从需求端就砍掉了一些难搞的网站,比如某程……常爬的比如某点评,某房,还有某电影,某居客也会偶尔爬一下。
也不能说爬虫这东西对人家都是害处,毕竟还贡献了不少访问量是不(大雾)但一定要注意点爬取的力度,以及该伪造的信息要伪造好。

2.1 准备
  1. 首先呢,ip代理池这东西最好要有。个人的话无所谓,被发现了封了就封了,但是对公司来说搞不好会被同事打的。
  2. headers伪造。该改的记得要改,User-Agent这个不用多说,这个都不改的话还是别爬了……Cookie,Host也挺关键的,某房针对不同页面的Cookie,Host都是动态的,找到生成的关系还是能破解的。Referer对某些网站也挺关键的,比如某点评会检测,可以统一设置成一个让人家没法说你是假的的网址。
  3. 速度控制。这个很关键,你隐藏的再好一秒钟几十个网址也太假了。而且本来就做着爬虫了还超额的给人家服务器增大负担,良心不会痛吗。
2.2 具体问题

程序真正跑起来都是不断调试的。说几个踩过的坑:

  1. 写好重试机制,比如一个url出错了就重试三遍。有些时候请求没有返回预期结果可能是各种原因并不单单是因为你的代码有问题。
  2. 写好续传机制,同上,别偶然出个错程序就崩了,然后你还不知道跑到了哪,从头开始?什么redis啊,mongo啊该用的用起来。
  3. 出了问题先想办法把问题简单化。比如说你的代理ip被人家怀疑了,要你输入验证码,这个时候不是先想办法破解掉验证码,这个需要的时间可能太久了,完全可以chrome挂上代理,浏览器访问一下点掉就好了。
    还有的一些网站加的验证比较蠢,比如说让你访问另一个url得到验证码,这种可以考虑下破解掉。
  4. 代码规范化,公用的部分封装好,注释写好,最好更新日期都带上
    这样一方面是有利于复用,另一方面也是避免代码混乱。面对那些经常更新html的网站把每一个版本的html解析都保存好,没准过几天它们就改回原版了,真的,别问我为什么知道。
  5. 代码结构设计
    比如说先爬搜索的列表页,获取每个页面的首页链接,再从首页获取详情页链接,xx页链接,再分别进入这两个页面抓必要信息。
    这时候上个mongodb会让整个过程清晰很多。

简单放下代码:

from fake_useragent import UserAgent
import requests
import time

s = requests.Session()
TIMEOUT = 10

def get_user_agent():
    ua = UserAgent()
    return ua.random

def get_sofang_headers(version, url):
    if version == "列表页":
        headers = {}
    elif version == "首页":
        headers = {}
    elif version == "详情页":
        headers = { ... }
    return headers

def fetch(url, retry=0, version="列表页"):
    if url:
        url = url.strip()
    if "http" not in url:
        return ""

    # 代理模式1
    choice_proxy_item = choice_dp_proxy()
    proxies = {
        'http': choice_proxy_item,
        'https': choice_proxy_item
    }
    # 代理模式2
    # from ..commons.common_params import proxy as proxies
    s.headers = get_sofang_headers(version=version, url=url)
    s.headers.update({'user-agent': get_user_agent()})
    try:
        res = s.get(url, timeout=TIMEOUT, proxies=proxies)

        if res.status_code != 200:
            print(res.status_code)
            raise Exception

        res.encoding = res.apparent_encoding
        return res

    except (requests.exceptions.RequestException,
            requests.exceptions.ProxyError) as e:
        if retry <= 3:
            print("休息会")
            time.sleep(2)
            return fetch(url, retry=retry + 1, version=version)
    except Exception as e:
        if e:
            print(e)
        if retry <= 3:
            print("着重休息会")
            time.sleep(2)
            return fetch(url, retry=retry + 1, version=version)

代理模式1

import random
DP_PROXIES = [
    'ip:port',
    ...
]

def choice_dp_proxy():
    if DP_PROXIES:
        return random.choice(DP_PROXIES)
    return ''"

代理模式2 -- 阿布云

# 代理服务器
proxyHost = "http-dyn.abuyun.com"
proxyPort = "9020"

# 代理隧道验证信息
proxyUser = ".."
proxyPass = ".."

proxyMeta = "http://%(user)s:%(pass)s@%(host)s:%(port)s" % {
    "host": proxyHost,
    "port": proxyPort,
    "user": proxyUser,
    "pass": proxyPass,
}

proxy = {
    "http": proxyMeta,
    "https": proxyMeta,
}

常用方法:

r = requests.get(url)
r.text               HTTP相应内容的字符串形式
r.content            HTTP相应内容的二进制形式
r.encoding           从HTTP的header中猜测编码方式
r.apprentencoding    备选编码,从内容中分析出的编码方式
r.status_code
r.request.url

异常处理
try:
    r = requests.get(url)
    r.raise_for_status()
    r.encoding = r.apprentencoding
except:
    ......

查看响应时间
r.elapsed.microseconds
3. app端

有时候网页端满足不了全部需求了,于是毒手又伸向了app。
比如说某德地图,要抓取它购物中心内的店铺信息。
嗯,这个时候需要借助一些软件了,我是选的mitm,感觉上手比较简单。
简单说下流程,就是

  1. 电脑上装好,启动,手机和电脑连同一wifi,指定ip、端口,手机上安装证书。
  2. 写好url解析脚本,电脑上重新启动服务,手机开始浏览需要的页面。
  3. 数据处理。

常用命令:

启动:  mitmproxy
启动python脚本过滤抓包:mitmdump -s xxx.py

xxx.py

class AmapCapture():
    def response(self, flow):
        """
        1. 文件以 req_date_time.json
        """
        t = time.time()*1000
        if "ws/valueadded/shopping/poi_list" in flow.request.url:
            f = open("res/res_{t}_{name}.json".format(t=t, name="上海森宏购物中心"), "wb")
            f.write(flow.response.content)
            f.close()

def start():
    return AmapCapture()
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,529评论 5 475
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,015评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,409评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,385评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,387评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,466评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,880评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,528评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,727评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,528评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,602评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,302评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,873评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,890评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,132评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,777评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,310评论 2 342