前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python爬虫的东西

python爬虫的东西

作者头像
热心的社会主义接班人
发布2018-11-27 13:13:22
8270
发布2018-11-27 13:13:22
举报
文章被收录于专栏:cscs

知网

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>

代码语言:javascript
复制
#这个是获取第二页的数据的方法,需要传入上面处理出来的页数
    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

其构造函数放在下面

代码语言:javascript
复制
  #底层的目录进行处理
    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 也很重要

代码语言:javascript
复制
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 (中国标准时间)
代码语言:javascript
复制
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()
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018.10.27 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档