专栏首页cspython爬虫的东西

python爬虫的东西

知网

image.png

这目录直接提取

image.png

<a class="fz14" href="/kns/detail/detail.aspx?QueryID=30&CurRec=2&dbcode=SOPD&dbname=SOPD2018&filename=USD828895(S1)" target="_blank">Trigger mechanism</a>

<a class="fz14" href="/kns/detail/detail.aspx?QueryID=30&CurRec=3&dbcode=SOPD&dbname=SOPD2018&filename=US10076922(B2)" target="_blank">Customizable document for producing a security document, customized security document and production of such a security document</a>

#这个是获取第二页的数据的方法,需要传入上面处理出来的页数
    def fanye(self,page):
        #第一页已经抓取了,从第二页开始,然后到最后一页
        for i in  range(2,page+1):
            #构造第二页的url
            page_url='http://kns.cnki.net/kns/brief/brief.aspx?curpage={0}&RecordsPerPage=50&QueryID=0&ID=&turnpage=1&tpagemode=L&dbPrefix=SCOD&Fields=&DisplayMode=listmode&PageName=ASP.brief_result_aspx&isinEn=0#J_ORDER&'.format(i)
            response=self.connect(page_url)
            soup=bs(response.text,'html.parser')
            #调用上面的获取详情的函数
            self.xq_url_get(soup)

image.png

<a href="?curpage=2&RecordsPerPage=20&QueryID=30&ID=&turnpage=1&tpagemode=L&dbPrefix=SCOD&Fields=&DisplayMode=listmode&PageName=ASP.brief_result_aspx&isinEn=0#J_ORDER&" title="键盘的“← →”可以实现快速翻页">2</a>

<a href="?curpage=3&RecordsPerPage=20&QueryID=30&ID=&turnpage=1&tpagemode=L&dbPrefix=SCOD&Fields=&DisplayMode=listmode&PageName=ASP.brief_result_aspx&isinEn=0#J_ORDER&" title="键盘的“← →”可以实现快速翻页">3</a>

目录提取,有img的有下一层。

image.png

image.png

image.png

目录是 NaviGroup

其这几个参数比较重要

Host: kns.cnki.net Referer: http://kns.cnki.net/kns/brief/result.aspx?dbprefix=CISD&catalogName=ZJCLS User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36

下面几个需要构造url

Query string parameters

code: A tpinavigroup: CISDtpiresult catalogName: ZJCLS __: Fri Oct 26 2018 18:31:53 GMT+0800 (中国标准时间)

image.png

其构造函数放在下面

  #底层的目录进行处理
    def children_tag(self):
        #由于是post请求,所以需要先构造相应的data
        from_data={
                 'ua':1.25,
                 'PageName': 'ASP.brief_result_aspx',
                 'DbPrefix': 'SCOD',
                 'DbCatalog': '专利数据总库',
                 'ConfigFile': 'SCOD.xml',
                 'db_opt': 'SCOD',
                 'db_value': '中国专利数据库,国外专利数据库',
                 'his': '0',
                 '__': '%s %s' % (time.strftime('%a %b %d %Y %H:%M:%S GMT+0800'), ' (中国标准时间)')}
        #遍历底层的目录
        for i in self.mulu_list:
            #底层目录的编号
            print(i)
            #需要传入的值,所以用字典的添加方式将值添加到from_data
            from_data['NaviCode']=i
            #这个访问的网站是做打开数据库的操作,让cookies出现在他们网页地图上,否则无法得到相应的数据
            ss = self.connect(searchHandler_url, data=from_data, mothed='POST')
            #访问失败则重新访问一次,如果还不可以则打印相应的url
            if ss==404:
                time.sleep(random.randint(5,7))
                ss = self.connect(searchHandler_url, data=from_data, mothed='POST')
                if ss==404:
                    print(searchHandler_url)
                else:
                    #成功则调用下面的函数,获得相应的数据页面
                    self.data_get()
            else:
                self.data_get()

image.png

Search页面的 fromdate 也很重要

action: 
NaviCode: A
catalogName: ZJCLS
ua: 1.25
isinEn: 0
PageName: ASP.brief_result_aspx
DbPrefix: CISD
DbCatalog: 标准数据总库
ConfigFile: CISD.xml
db_opt: CISD
his: 0
__: Fri Oct 26 2018 18:37:02 GMT+0800 (中国标准时间)
import requests, random,re
from settings import *
from multiprocessing import Process,queues
from bs4 import BeautifulSoup as bs

searchHandler_url='http://kns.cnki.net/kns/request/SearchHandler.ashx'
data_url='http://kns.cnki.net/kns/brief/brief.aspx'
mulu_list=['A','B','C','D','E','F','G','H','I','J']

# 连接类(——主要作用用requests访问页面——)
class Conect(object):
    #连接方法,用requests访问网站,有两种方法(post和get)
    def connect(self, url, proxies=None, mothed='GTE', data=None):
        #无法访问进行3次尝试,如果还不行,就返回404
        for z in range(1, 4):
            #异常捕获,否则无法访问则会报错
            try:
                if mothed == 'GTE':
                    response = self.s.get(url, headers=self.headers,data=data, proxies=proxies, timeout=90)

                else:
                    response = self.s.post(url, data=data, headers=self.headers, proxies=proxies, timeout=90)
            #错误则进行休眠
            except Exception:
                print('无法连接网络,正在进行第%d次尝试' % z)
                time.sleep(random.randint(3, 7))
                #判断已经访问错误几次了,如果大于等于3,则返回404,反之则跳过
                if z < 3:
                    pass
                else:
                    print('三次未访问成功的网站:', url)
                    # 这里将无法访问3次则记录错误信息日志记录
                    return 404
            #网页中可能本身存在404,找不到网页的情况,这种时候直接返回404
            else:
                if response.status_code == 404:
                    return 404

                #正常情况,返回的是网页源码,解码格式我直接采用了utf-8,可根据网站需要更换
                else:
                    response.encoding = 'utf-8'
                    return response

#主程序
class zhiwang_zhuanli(Conect):
    #创建Session,可自动记录访问的cookies
    s = requests.Session()
    #访问的请求头
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36',
        'Host': 'login.cnki.net',
        'Referer': 'http://www.cnki.net/'
    }
    #这个列表是用来装底层目录的列表
    mulu_list=[]
    #由于是多进程,所以需要类接收一个参数,最外层目录编号
    def __init__(self,code_abc):
        self.__go__(code_abc)

    # 运行程序(一般多线程都放在这个函数里面)
    def __go__(self,code_abc):
        #由于我无法确定每个有多少层目录,所以我用递归的方式,调用了反复调用自身,传入的长度首先是2
        lenge=len(code_abc)
        while lenge>0:
            #对code_abc进行重新赋值,可以减小反复占用内存
            code_abc=self.mulu(code_abc)
            #对lenge重新赋值,重复调用本身函数,直到无二级以上的分类为止
            lenge=len(code_abc)
        #处理底层目录
        self.children_tag()


    #未用上,这个本来是可以改变Session的cookies,但是我发现后面也可以获得cookies
    def cookies_get(self):
        rsponse=404
        while rsponse==404:
            rsponse=self.connect(login_url,proxies=self.proxies)
            time.sleep(random.randint(4,10))

    #对目录进行处理的方法,每次访问一层,直到全部底层的目录的都加入到self.mulu_list
    def mulu(self,code_abc):
        #修改referer,否则无法拿到值
        self.headers['Referer'] = 'http://kns.cnki.net/kns/brief/result.aspx?dbprefix=SCOD'
        #host也不同,所以要做修改
        self.headers['Host']='kns.cnki.net'
        #创建一个非底层目录保存列表
        f_list=[]
        # 用遍历的方式来访问每个非底层的目录
        for i in code_abc:
            #构造需要访问的url
            mulu_url_pj=mulu_url+'?code='+i+'&tpinavigroup='+'SCODtpiresult'+'&__='+time.strftime('%a %b %d %Y %H:%M:%S GMT+0800')
            #访问相应的url
            sz=self.connect(mulu_url_pj)
            #判断,如果访问为404,则pass
            if sz==404:
                print('目录访问失败!')
            else:
                #访问成功的进行解析
                soup=bs(sz.text,'html.parser')
                dd=soup.findAll('dd')
                for dd_tag in dd:
                    img=dd_tag.find('img')
                    xuhao_tag=dd_tag.find('a').get('onclick')
                    if img==None:
                        #提取序号
                        bianhao=self.dd_re(xuhao_tag)
                        #将底层的目录放在类的列表中
                        self.mulu_list.append(bianhao)
                    else:
                        #将非底层的目录放在一个列表中
                        bianhao=self.dd_re(xuhao_tag)
                        f_list.append(bianhao)
        #返回非底层的列表
        return f_list


    # 对编号进行裁剪,得到相应的值
    def dd_re(self, string):
        xuhao = re.split('\'', string)[1]
        return xuhao


    #底层的目录进行处理
    def children_tag(self):
        #由于是post请求,所以需要先构造相应的data
        from_data={
                 'ua':1.25,
                 'PageName': 'ASP.brief_result_aspx',
                 'DbPrefix': 'SCOD',
                 'DbCatalog': '专利数据总库',
                 'ConfigFile': 'SCOD.xml',
                 'db_opt': 'SCOD',
                 'db_value': '中国专利数据库,国外专利数据库',
                 'his': '0',
                 '__': '%s %s' % (time.strftime('%a %b %d %Y %H:%M:%S GMT+0800'), ' (中国标准时间)')}
        #遍历底层的目录
        for i in self.mulu_list:
            #底层目录的编号
            print(i)
            #需要传入的值,所以用字典的添加方式将值添加到from_data
            from_data['NaviCode']=i
            #这个访问的网站是做打开数据库的操作,让cookies出现在他们网页地图上,否则无法得到相应的数据
            ss = self.connect(searchHandler_url, data=from_data, mothed='POST')
            #访问失败则重新访问一次,如果还不可以则打印相应的url
            if ss==404:
                time.sleep(random.randint(5,7))
                ss = self.connect(searchHandler_url, data=from_data, mothed='POST')
                if ss==404:
                    print(searchHandler_url)
                else:
                    #成功则调用下面的函数,获得相应的数据页面
                    self.data_get()
            else:
                self.data_get()


    #获得数据列表的网站,这个只是访问第一页,后面几页需要重新构造
    def data_get(self):
        #这里由于headers都是一样的,所以我没有做修改
        url=data_url+'?'+'pagename=ASP.brief_result_aspx&'+'isinEn=0&'+'dbPrefix=SCOD&'+'dbCatalog=%e4%b8%93%e5%88%a9%e6%95%b0%e6%8d%ae%e6%80%bb%e5%ba%93&'+"ConfigFile=SCOD.xml&"+'research=off&'+'S=1'
        response=self.connect(url)
        #访问失败则跳过
        if response==404:
            print(url)
        else:
            #访问成功的则对页面做后面的处理
            page=self.data_re(response)
            self.fanye(page)

    #获取页数的函数
    def data_re(self,response):
        #解析打开的网页
        text=response.text
        soup=bs(text,'html.parser')
        #抓取包含页数的地方,如果抓不到,则代表没有第二页,则返回0
        page=soup.find('span',{'class':'countPageMark'})
        if page==None:
            #这里调用的方法是获取文章详情的url
            self.xq_url_get(soup)
            return 0
        else:

            self.xq_url_get(soup)
            #由于抓取到的是字符串,而且都是1/%d,这种格式,所以我直接裁掉前面的,得到页数
            num=re.sub('1/','',page.text)
            #返回int型页数
            return int(num)

    #这个是获取第二页的数据的方法,需要传入上面处理出来的页数
    def fanye(self,page):
        #第一页已经抓取了,从第二页开始,然后到最后一页
        for i in  range(2,page+1):
            #构造第二页的url
            page_url='http://kns.cnki.net/kns/brief/brief.aspx?curpage={0}&RecordsPerPage=50&QueryID=0&ID=&turnpage=1&tpagemode=L&dbPrefix=SCOD&Fields=&DisplayMode=listmode&PageName=ASP.brief_result_aspx&isinEn=0#J_ORDER&'.format(i)
            response=self.connect(page_url)
            soup=bs(response.text,'html.parser')
            #调用上面的获取详情的函数
            self.xq_url_get(soup)


    #每页中都有文章详情的链接,所以用这个方法提取
    def xq_url_get(self,soup):
        xq_url_tag = soup.find('table', {'class': "GridTableContent"})
        xq_url_list = xq_url_tag.findAll('a')
        for url in xq_url_list:
            # print('文章网站:', 'http://kns.cnki.net' + url.get('href'))
            pass


if __name__ == '__main__':
    #五个进程,调试的时候我用的是一个
    # for i in range(5):
    for i in range(1):
        P1=Process(target=zhiwang_zhuanli,args=([mulu_list[i],mulu_list[9-i]],))
        P1.start()

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • python类与对象

    东风冷雪
  • python下载万方数据库文献

    东风冷雪
  • 知识点找回2.0

    Servlet(server Applet),全称Java Servlet, 是用java编写的服务器端程序。而这些Servlet都要实现Servlet的这个借...

    东风冷雪
  • 爬虫学习(二)

    To understand and be understood, those are among life’s greatest gifts, and ever...

    小闫同学啊
  • pygame-KidsCanCode系列jumpy-part1-如何组织复杂游戏的代码

    武侠小说中,高手过招讲究起手式,所谓"行家一伸手,便知有没有"。程序开发、软件架构中,也是类似的道理,当业务逻辑越来越复杂,代码越来越多时,一个好的项目结构,从...

    菩提树下的杨过
  • pygame-KidsCanCode系列jumpy-part18-背景滚动

    2. 兔子向上跳时,(背景)白云也要相应的滚动,但是为了视觉效果,速度要低于档板的速度(比如:1/2 or 1/3)。

    菩提树下的杨过
  • iOS开发之微信聊天页面实现

      在上篇博客(iOS开发之微信聊天工具栏的封装)中对微信聊天页面下方的工具栏进行了封装,本篇博客中就使用之前封装的工具栏来进行聊天页面的编写。在聊天页面中主要...

    lizelu
  • 局部敏感哈希(原始LSH)python实

    最近短期计划是学习一下Python,最好的学习方式当然是实践了,今天用Python实现了下lsh算法,代码比较简陋。。。(2016.1.17)

    py3study
  • python中 _、__、__xx__()区别及使用场景

    在面向对象编程语言中,类的属性与方法都会设置访问控制权限,从而满足我们的设计需求。一般而言,我们通常会将对象的属性设置为私有的(private)或受保护的(pr...

    砸漏
  • python网络爬虫(10)分布式爬虫爬取静态数据

    爬虫应该能够快速高效的完成数据爬取和分析任务。使用多个进程协同完成一个任务,提高了数据爬取的效率。

    嘘、小点声

扫码关注云+社区

领取腾讯云代金券