来自  资质荣誉 2019-11-28 15:03 的文章
当前位置: 澳门太阳娱乐手机登录 > 资质荣誉 > 正文

Python爬取腾讯网与本身所领会的爬虫与反爬虫,

近来在练习写爬虫的时候,正好同学的女对象有须求,大致是爬取知网内的几千个核心的数据,每二个主旨的条数记录有几条的到几千条的不等,总来的来讲也算是个上万数据级的爬虫了,分析了下知网,开采使用正规检索,能够产生自个儿的指标,然后经过chrome的developer tools大约解析了下了哀告数据包,发掘知网的询问是分成两步的,第一步是多个总的央浼(查询的条件基本上都在率先步里面了卡塔 尔(英语:State of Qatar),会回到二个串

果壳网已经成为了爬虫的篮球馆,本文利用Python中的requests库,模拟登入果壳网,获取cookie,保存到地头,然后这么些cookie作为登入的证据,登入博客园的主页面,爬取博客园主页面上的标题和相应难题答问的摘要。

至于网易验证码登录的主题材料,用到了Python上三个要害的图形管理库PIL,假设那二个,就把图纸存到本地,手动输入。

图片 1

爬取网易的主要的片段:模拟登入

由此对天涯论坛登录是的抓包,能够开掘登录果壳网,须要post多少个参数,叁个是账号,叁个是密码,四个是xrsf。
以此xrsf隐敝在表单里面,每回登录的时候,应该是服务器随机爆发三个字符串。全部,要效仿登录的时候,必要求得到xrsf。

用chrome (大概火狐 httpfox 抓包深入分析卡塔 尔(英语:State of Qatar)的结果:

image.png

就此,应当要获得xsrf的数值,注意那是一个动态变化的参数,每便都不相仿。

image.png

注意findall和find_all函数的不相同。

获得xsrf,下面就足以依样画葫芦登录了。
选用requests库的session对象,构建叁个对话的裨益是,能够把同二个顾客的差别央浼联系起来,直到会话停止都会活动管理cookies。

image.png

精心:cookies 是当前目录的三个文件,那一个文件保留了今日头条的cookie,借使是第叁个登陆,那么自然是未曾这么些文件的,无法透过cookie文件来登录。应当要输入密码。

def login(secret, account):
    # 通过输入的用户名判断是否是手机号
    if re.match(r"^1d{10}$", account):
        print("手机号登录 n")
        post_url = 'https://www.zhihu.com/login/phone_num'
        postdata = {
            '_xsrf': get_xsrf(),
            'password': secret,
            'remember_me': 'true',
            'phone_num': account,
        }
    else:
        if "@" in account:
            print("邮箱登录 n")
        else:
            print("你的账号输入有问题,请重新登录")
            return 0
        post_url = 'https://www.zhihu.com/login/email'
        postdata = {
            '_xsrf': get_xsrf(),
            'password': secret,
            'remember_me': 'true',
            'email': account,
        }
    try:
        # 不需要验证码直接登录成功
        login_page = session.post(post_url, data=postdata, headers=headers)
        login_code = login_page.text
        print(login_page.status_code)
        print(login_code)
    except:
        # 需要输入验证码后才能登录成功
        postdata["captcha"] = get_captcha()
        login_page = session.post(post_url, data=postdata, headers=headers)
        login_code = eval(login_page.text)
        print(login_code['msg'])
    session.cookies.save()
try:
    input = raw_input
except:
    pass

那是登录的函数,通过login函数来登入,post 本身的账号,密码和xrsf 到博客园登录认证的页面上去,然后拿走cookie,将cookie保存到当前目录下的文书之中。后一次登录的时候,直接读取那么些cookie文件。

#LWP-Cookies-2.0
Set-Cookie3: cap_id=""YWJkNTkxYzhiMGYwNDU2OGI4NDUxN2FlNzBmY2NlMTY=|1487052577|4aacd7a27b11a852e637262bb251d79c6cf4c8dc""; path="/"; domain=".zhihu.com"; path_spec; expires="2017-03-16 06:09:37Z"; version=0
Set-Cookie3: l_cap_id=""OGFmYTk3ZDA3YmJmNDQ4YThiNjFlZjU3NzQ5NjZjMTA=|1487052577|0f66a8f8d485bc85e500a121587780c7c8766faf""; path="/"; domain=".zhihu.com"; path_spec; expires="2017-03-16 06:09:37Z"; version=0
Set-Cookie3: login=""NmYxMmU0NWJmN2JlNDY2NGFhYzZiYWIxMzE5ZTZiMzU=|1487052597|a57652ef6e0bbbc9c4df0a8a0a59b559d4e20456""; path="/"; domain=".zhihu.com"; path_spec; expires="2017-03-16 06:09:57Z"; version=0
Set-Cookie3: q_c1="ee29042649aa4f87969ed193acb6cb83|1487052577000|1487052577000"; path="/"; domain=".zhihu.com"; path_spec; expires="2020-02-14 06:09:37Z"; version=0
Set-Cookie3: z_c0=""QUFCQTFCOGdBQUFYQUFBQVlRSlZUVFVzeWxoZzlNbTYtNkt0Qk1NV0JLUHZBV0N6NlNNQmZ3PT0=|1487052597|dcf272463c56dd6578d89e3ba543d46b44a22f68""; path="/"; domain=".zhihu.com"; path_spec; expires="2017-03-16 06:09:57Z"; httponly=None; version=0

那是cookie文件的内容

以下是源码:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import requests
try:
    import cookielib
except:
    import http.cookiejar as cookielib
import re
import time
import os.path
try:
    from PIL import Image
except:
    pass

from bs4 import BeautifulSoup


# 构造 Request headers
agent = 'Mozilla/5.0 (Windows NT 5.1; rv:33.0) Gecko/20100101 Firefox/33.0'
headers = {
    "Host": "www.zhihu.com",
    "Referer": "https://www.zhihu.com/",
    'User-Agent': agent
}

# 使用登录cookie信息
session = requests.session()
session.cookies = cookielib.LWPCookieJar(filename='cookies')
try:
    session.cookies.load(ignore_discard=True)
except:
    print("Cookie 未能加载")



def get_xsrf():
    '''_xsrf 是一个动态变化的参数'''
    index_url = 'https://www.zhihu.com'
    # 获取登录时需要用到的_xsrf
    index_page = session.get(index_url, headers=headers)
    html = index_page.text
    pattern = r'name="_xsrf" value="(.*?)"'
    # 这里的_xsrf 返回的是一个list
    _xsrf = re.findall(pattern, html)
    return _xsrf[0]





# 获取验证码
def get_captcha():
    t = str(int(time.time() * 1000))
    captcha_url = 'https://www.zhihu.com/captcha.gif?r=' + t + "&type=login"
    r = session.get(captcha_url, headers=headers)
    with open('captcha.jpg', 'wb') as f:
        f.write(r.content)
        f.close()
    # 用pillow 的 Image 显示验证码
    # 如果没有安装 pillow 到源代码所在的目录去找到验证码然后手动输入
    try:
        im = Image.open('captcha.jpg')
        im.show()
        im.close()
    except:
        print(u'请到 %s 目录找到captcha.jpg 手动输入' % os.path.abspath('captcha.jpg'))
    captcha = input("please input the captchan>")
    return captcha





def isLogin():
    # 通过查看用户个人信息来判断是否已经登录
    url = "https://www.zhihu.com/settings/profile"
    login_code = session.get(url, headers=headers, allow_redirects=False).status_code
    if login_code == 200:
        return True
    else:
        return False


def login(secret, account):
    # 通过输入的用户名判断是否是手机号
    if re.match(r"^1d{10}$", account):
        print("手机号登录 n")
        post_url = 'https://www.zhihu.com/login/phone_num'
        postdata = {
            '_xsrf': get_xsrf(),
            'password': secret,
            'remember_me': 'true',
            'phone_num': account,
        }
    else:
        if "@" in account:
            print("邮箱登录 n")
        else:
            print("你的账号输入有问题,请重新登录")
            return 0
        post_url = 'https://www.zhihu.com/login/email'
        postdata = {
            '_xsrf': get_xsrf(),
            'password': secret,
            'remember_me': 'true',
            'email': account,
        }
    try:
        # 不需要验证码直接登录成功
        login_page = session.post(post_url, data=postdata, headers=headers)
        login_code = login_page.text
        print(login_page.status_code)
        print(login_code)
    except:
        # 需要输入验证码后才能登录成功
        postdata["captcha"] = get_captcha()
        login_page = session.post(post_url, data=postdata, headers=headers)
        login_code = eval(login_page.text)
        print(login_code['msg'])
    session.cookies.save()
try:
    input = raw_input
except:
    pass



## 將main的問題列表輸出在shell上面
def  getPageQuestion(url2):  
  mainpage = session.get(url2, headers=headers)
  soup=BeautifulSoup(mainpage.text,'html.parser')
  tags=soup.find_all("a",class_="question_link")
  #print tags

  for tag in tags:
    print tag.string

# 將main頁面上面的問題的回答的摘要輸出在shell上面
def getPageAnswerAbstract(url2):
    mainpage=session.get(url2,headers=headers)
    soup=BeautifulSoup(mainpage.text,'html.parser')
    tags=soup.find_all('div',class_='zh-summary summary clearfix')

    for tag in tags:
       # print tag
        print tag.get_text()
        print '詳細內容的鏈接 : ',tag.find('a').get('href')


def getPageALL(url2):
    #mainpage=session.get(url2,headers=headers)
    #soup=BeautifulSoup(mainpage.text,'html.parser')
    #tags=soup.find_all('div',class_='feed-item-inner')
    #print "def getpageall "
    mainpage=session.get(url2,headers=headers)
    soup=BeautifulSoup(mainpage.text,'html.parser')
    tags=soup.find_all('div',class_='feed-content')
    for tag in tags:
        #print tag
        print tag.find('a',class_='question_link').get_text()
        # 這裏有一點問題 bs 還是用的不是太熟練
        #print tag.find('a',class_='zh-summary summary clearfix').get_text()
        #print tag.find('div',class_='zh-summary summary clearfix').get_text()


if __name__ == '__main__':
    if isLogin():
        print('您已经登录')
        url2='https://www.zhihu.com'
        # getPageQuestion(url2)
        #getPageAnswerAbstract(url2)
        getPageALL(url2)
    else:
        account = input('请输入你的用户名n>  ')
        secret = input("请输入你的密码n>  ")
        login(secret, account)

运营结果:

image.png

然后技术做第二步的多寡央浼(下方的截图对应网页上的两样区域的乞请报文头和再次回到数据卡塔 尔(阿拉伯语:قطر‎

git链接:

https://github.com/zhaozhengcoder/Spider/tree/master/spider_zhihu

图片 2

PPS:作者所明白的爬虫与反爬虫计谋

反爬虫最核心的国策:

  1. 自己商议浏览器http诉求里面包车型大巴user-agent字段
  2. 反省http诉求的referer(即当前的那一个页面是从哪个页面跳转过来的卡塔 尔(阿拉伯语:قطر‎

爬虫战术:
那八个都是在http左券的报文段的反省,相近爬虫端能够很有益于的安装这么些字段的值,来乘机而入服务器。

反爬虫进级计策:
1.像天涯论坛相似,在签到的表单里面放入三个隐讳字段,里面会有二个随便数,每趟都不均等,那样除非你的爬虫脚本能够解析这一个自由数,不然后一次爬的时候就可怜了。
2.笔录探访的ip,计算访谈次数,就算次数太高,能够感觉这些ip反常。

爬虫晋级攻略:
1.像那篇文章提到的,爬虫也能够先深入分析一下隐敝字段的值,然后再进行模拟登陆。
2.爬虫能够应用ip代理池的方法,来幸免被察觉。同期,也得以爬一会休憩一会的点子来下滑效能。其余,服务器依照ip访谈次数来进行反爬,再ipv6未有两全推广的不时,那个政策会超级轻松引致风险。(那几个是自己个人的领会卡塔 尔(英语:State of Qatar)。

反爬虫进进级战术:
1.数额投毒,服务器在本身的页面上放置超多掩蔽的url,那些url存在于html文件文件之中,不过透过css可能js使她们不会被出示在客商观望标页面上面。(确认保障客户点击不到卡塔尔。那么,爬虫在爬取网页的时候,很用或然取采访这几个url,服务器能够百分之百的以为这是爬虫干的,然后能够回来给他有的错误的多寡,也许是不容响应。

爬虫进升级战术:
1.生龙活虎一网址即使必要反爬虫,不过不可以知道把百度,Google那般的查找引擎的爬虫给干了(干了的话,你的网址在百度都在说搜不到!卡塔尔国。这样爬虫应该就能够虚构是百度的爬虫去爬。(但是ip恐怕恐怕被查出,因为您的ip并不是百度的ip卡塔尔

反爬虫进进升级战术:
给个验证码,让您输入现在技艺登录,登录之后,工夫访谈。

爬虫进进进级计策:
图像识别,机器学习,识别验证码。但是这几个理应相比难,大概说花销相比高。

仿照效法资料:
廖雪峰的python教程
静觅的python教程
requests库官方文书档案
segmentfault下面有壹人的有关果壳网爬虫的博客,找不到链接了

                                                                       图意气风发.询问记录诉求报文头

图片 3

                                                                        图二. 对应不一致年份的记录条数重返结果

有关缘何要分成两步,每二个区域对应三个比不上的哀求,这几个都是网址本人的宏图,小编也没做过web开辟,这么做有怎么样优点小编确实不晓得/擦汗,作者的首要性正是仿照它在网页上的伸手,达成批量化的多寡获得。

 

然后,大概就摸清楚了那叁个数目获得的进度,小编的笔触是先达成叁个数额级的多少拿到,也正是爬取一条,然后再去扩张,加线程,加ip代理,加user_agent等等。

在这里个阶段,主要的思绪正是大半要和在网页上的拜见保持生龙活虎致,保障本人拼的url和在网页上访问的时候是毫发不爽的,当然是在确认保障能访谈的前提下,能略去的就略去。

深入分析它原先的伸手url的时候,使用url转码工具得以将转码以往的url还原,越来越直白地解析。

然后提多少个细节呢,知网的号召url上,有风度翩翩对数码段生机勃勃初步是不知道它的意义的,可是自身去拼接访谈的时候开采,缺了网址就能够报错,此时就足以多尝试多少个例外的访谈,去拿它的央求heads,然后互绝相比,就能意识一些字段是定位不改变的,这种就能够一贯照搬,有的吧,是浮动的,这种就供给用心去解析到底是何许数据,有啥样含义,知网的就包涵一个飞秒数,这么些自家一齐初就没懂具体意思,后来深入分析了下认为像时间,然后去取了下当前的毫秒时间,后生可畏比较发掘大概是大半,就当前的飞秒时间拼在了url串上边。

def getMilliTim():
    t = time.time()
    nowTime = t*1000
    return int(nowTime)

即便你需求多少个卓越的上学交流条件,那么您能够酌量Python学习调换群:548377875; 假设您供给风姿洒脱份系统的读书资料,那么您可以伪造Python学习沟通群:548377875。

简单的说,就是对于有个别懂web的爬虫小白,最佳正是还原网址原来的伸手,那样基本上央浼数据就不会有太大难点了。

在成就了多少级为生龙活虎的等级后,就起来策动大面积地获取数据了,那时就要考虑功效以至防守网址踢人了。

在非常受了各类socket 10054 10061等不当,通过百度种种才干,加上了ip代理等一些格局,最后本人恐怕成功此次任务,当然最终如故增加了文本读取,职责队列等模块,大约就是一个线程专责输出文件,其余四个线程去职责池里面取职分爬数据,详细略过,见代码。有疏漏之处,还请斧正。

本文由澳门太阳娱乐手机登录发布于 资质荣誉,转载请注明出处:Python爬取腾讯网与本身所领会的爬虫与反爬虫,

关键词: