zoukankan      html  css  js  c++  java
  • python爬虫第六天

     
     
    今天继续学习一些实战爬虫
     
    链接爬虫实战
     
        要求:把一个网页里所有的链接地址提取出来
        思路:(1)确定爬取的入口链接
                  (2)构建提取链接的正则表达式
                  (3)模拟浏览器爬取网页
                  (4)根据正则表达式提取链接
                  (5)过滤掉重复的链接
                  (6)后续操作
     
    比如我们来获取    http://blog.csdn.net/下的链接
     
    import re
    import urllib.request
    import urllib.error
    def getlink(url):
        #模拟浏览器访问
        headers=('User-Agent','Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36')
        opener=urllib.request.build_opener()
        opener.addheaders=[headers]
        #将opener安装成全局
        urllib.request.install_opener(opener)
        file=urllib.request.urlopen(url)
        data=str(file.read())
        #构建正则表达式
        pat='(https?://[^s)";]+.(w|/)*)'
       #
        link=re.compile(pat).findall(data)
       #去除重复元素,只需要将link设为set集合再转为list就可以了
     
        link=list(set(link))
        return link
     
    #要爬取得网页
    url="http://blog.csdn.net/"
    linklist=getlink(url)
    for link in linklist:
        print(link[0])
     
     
    获取成功,这里需要弄懂的是链接的正则表达式,很多地方都有用:(https?://[^s)";]+.(w|/)*)
     
    糗事百科爬虫实战
    我们先来分析各个网页的网址规律,构造网址变量,通过for循环爬取多页的内容
    实现一个自定义函数专门用来爬取某网页的段子,这里和我们上次爬取图片差不多
    import re
    import urllib.request
    import urllib.error
    def getcontent(url,page):
        #--------
        # 模拟浏览器访问
        headers = ('User-Agent',
                   'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36')
        opener = urllib.request.build_opener()
        opener.addheaders = [headers]
        # 将opener安装成全局
        urllib.request.install_opener(opener)
           #---------
        data=urllib.request.urlopen(url).read().decode("utf-8")
     
        #构建对应用户提取的正则表示
        userpat='alt="(.*?)">'
        #构建段子内容提取的正则表达式
        contentpat='<div class="content">(.*?)</div>'
        #寻找所有的用户
        userlist=re.compile(userpat,re.S).findall(data)
        #寻找所有的内容
        contentlist=re.compile(contentpat,re.S).findall(data)
     
        x=1
        #循环遍历段子内容并赋值
        for content in contentlist:
            #去除换行
            content=content.replace(" ","")
            content = content.replace("<span>", "")
            content = content.replace("<br/>", "")
            content = content.replace("</span>", "")
            #用字符串作为变量名,先将对应的字符串赋值给一个变量
            name="content"+str(x)
            #exec函数实现用字符串作为变量名并且赋值
            exec(name+'=content')
            x+=1
        y=1
        #遍历用户,输出用户对应内容
        for user in userlist:
            name="content"+str(y)
     
            print("用户"+str(page)+str(y)+"是:"+user)
            print("内容是:")
            exec("print("+name+")")
            print(" ")
            y+=1
        #执行循环获取
    for i in range(1,10):
        url="http://www.qiushibaike.com/text/page/"+str(i)
        getcontent(url,i)
     
     
    现在这个网站改版了,爬取的内容好像显示不全。网站代码改版,我们就要更换url和正则表达式,否则爬不到,自己分析网页结构,做到灵活运用。
    现在知道如何爬取网页范围内的文字,并且自己能给出一些修饰删减就好了。
     
     
    微信文章爬虫实战
     
     
    我们在爬取微信的时候会比较麻烦,因为我们的ip会经常被封杀。那么我们就要解决这个问题。
    首先我们人工进行查阅,再用爬虫自动化。我们先进入搜狗的搜索平台:http://weixin.sougou.com
    我们分析一下发现如果没有type字段则搜索的不是文章。query是我们请求关键词的信息,我输入的关键词是物联网。
    我们点击下一页发现
    page字段出现了为2,所以是控制页数的字段。接下来我们构造网址
     
    我们接着再观察源代码:
    <div class="txt-box">
    <h3>
    <a target="_blank" href="http://mp.weixin.qq.com/s?src=11&amp;timestamp=1548826683&amp;ver=1397&amp;signature=DUmrUskDf4kb9Th4olLcy2F2Li51-*RrCB6cXU2XWjTxiekW6y5qX4MCG9xKlcv5ezvo8vylV5ku9hqEs7H0MraeRAE8n9LEJU4C-IK6C1N4MS-PqLaUKZvd-3H-b9K2&amp;new=1" id="sogou_vr_11002601_title_0" uigs="article_title_0" data-share="http://weixin.sogou.com/api/share?timestamp=1548826683&signature=qIbwY*nI6KU9tBso4VCd8lYSesxOYgLcHX5tlbqlMR8N6flDHs4LLcFgRw7FjTAONa2V-2x1W7AuuzD-vidXm3GvlytfD8sJy6-UegQq2dXx0gPni92wd2H9cr4shLXudn7EEa0mG*bje1CgQ1SR-P8d6sgbQ1VL0s2tJAntd0Vk-pwsL-vVvo1Uywe4YR*hx*PHSUyQNaBBUB185MtR9P4yramVOBzGCkA2Z2uWLZo=">[<em><!--red_beg-->物联网<!--red_end--></em>]是中国的!<em><!--red_beg-->物联网<!--red_end--></em>时代,且看中国!</a>
     
    得到正则表达式:     '<div class="tex-box">.*?(http://.*?)"'
    这样我们可以使用相关函数提取出指定页数的文章网址出来
    但是我们访问的时候发现网址参数错误,这时我们直接通过列表打开网址。发现提取出来的网址比真实的网址的多了&amp
    我们可以使用replace将其代替为""即可,关于封ip的情况就要用到我们之前学习的代理ip
     
    规划一下:我们要实现三个函数
    一个是使用代理服务器爬取指定的网址并返回数据,一个是获取多个页面文章链接的功能,最后一个根据文章链接爬取指定标题和内容。
    代码中如果发生异常,我们就要进行延时处理:使用time.sleep(7)方法延时7秒
    import re
    import time
    import urllib.request
    import urllib.error
    # 1模拟浏览器访问
    headers = ('User-Agent',
               'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36')
    opener = urllib.request.build_opener()
     
    opener.addheaders = [headers]
    # 将opener安装成全局
    urllib.request.install_opener(opener)
    # ---------
    listurl=[]
     
    def use_proxy(proxy_addr,url):
        try:
            import urllib.request
            proxy = urllib.request.ProxyHandler({'http': proxy_addr})
            opener = urllib.request.build_opener(proxy, urllib.request.HTTPHandler)
            urllib.request.install_opener(opener)
            data = urllib.request.urlopen(url).read().decode('utf-8')
            return data
        except urllib.error.URLError as e:
            if hasattr(e,"code"):
                print(e.code)
            if hasattr(e,"reason"):
                print(e.reason)
            time.sleep(10)
        except Exception as e:
            print("exception:"+str(e))
            time.sleep(1)
     
    def getlisturl(key,pagestart,pageend,proxy):
        try:
            page=pagestart
     
            keycode=urllib.request.quote(key)
            pagecode=urllib.request.quote("&page")
            for page in range(pagestart,pageend+1):
                url="http://weixin.sogou.com/weixin?type=2&query="+keycode+pagecode+str(page)
                #print("下面出不来"+url)#这里的url有点问题好像
          #pagecode=urllib.request.quote("&page")我不太清楚这里为什么要编码
          #我想改成不编码
          #pagecode=urllib.request.quote("page")
          #url="http://weixin.sogou.com/weixin?type=2&query="+keycode+"&"+pagecode+"="+str(page)
    #但是这里ip有点问题,看下面
                data1=use_proxy(proxy,url)
            #这里data1输出为None,不知是不是IP不能用的问题
                print(data1)
                
                listurlpat='<div class="txt-box">.*?(http://.*?)"'
                #print("哎呀前面没错哦")
                listurl.append(re.compile(listurlpat,re.S).findall(data1))
            print("获取到:"+str(len(listurl))+"页")
            return listurl
        except urllib.error.URLError as e:
            if hasattr(e, "code"):
                print(e.code)
            if hasattr(e, "reason"):
                print(e.reason)
            time.sleep(7)
        except Exception as e:
            print("exception:" + str(e))
            time.sleep(1)
     
    def getcontent(listurl,proxy):
        i=0
        html1='''<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
      <title> 微信文章页面</title>
      <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
      
    </head>
    <body>'''
        fh=open("D:/crawler/weixin/1.html","wb")
        fh.write(html1.encode("utf-8"))
        fh.close()
     
        fh=open("D:/crawler/weixin/1.html","ab")
     
        for i in range(0,len(listurl)):
            for j in range(0,len(listurl[i])):
                try:
                    url=listurl[i][j]
                    url=url.replace("amp;","")
                    data=use_proxy(proxy,url)
     
                    titlepat="<title>(.*?)</title>"
                    contentpat='id="js_content">(.*?)id="js_sq_bar"'
                    title=re.compile(titlepat).findall(data)
                    content=re.compile(contentpat,re.S).findall(data)
                    thistitle="此次没有获取到"
                    thiscontent="此次没有获取到"
                    if(title!=[]):
                        thistitle=title[0]
                    if(content!=[]):
                        thiscontent=content[0]
                    dataall="<p>标题为:"+thistitle+"</p><p>内容为:"+thiscontent+"</p>
    "
                    fh.write(dataall.encode("utf-8"))
                    print("第"+str(i)+"网页第"+str(j)+"次处理")
                except urllib.error.URLError as e:
                    if hasattr(e, "code"):
                        print(e.code)
                    if hasattr(e, "reason"):
                        print(e.reason)
                    time.sleep(10)
                except Exception as e:
                    print("exception:" + str(e))
                    time.sleep(1)
                    fh.close()
                    html2='''</body></html>'''
                    fh=open("D:/crawler/weixin/1.html","ab")
                    fh.write(html2.encode("utf-8"))
                    fh.close()
    #设置关键词
     
    key="物联网"
    #代理ip
    proxy="27.29.77.113"
    proxy2=""
    pagestart=1
    pageend=2
    listurl=getlisturl(key,pagestart,pageend,proxy)
     
    getcontent(listurl,proxy)
    这里要么是代理ip那边出了问题,换了很多ip还是连接不上。可能是url拼接的有点问题,但是我改过后仍然有异常,
    [WinError 10060] 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。
    这个弄了一天,还没有解决。。心累。。有大佬看出来错误还请指出来,在下谢谢了。
    要过年了。。提前祝大家新年快乐哈!
     
     
     
    此文是我在学习《精通Python网络爬虫》(韦玮著)的总结,纯手打。
     
     
     
     
     
     
     
     
     
  • 相关阅读:
    LVDS汇总
    smtp模块+Gmail搭建邮件发送功能
    网站建立(杂)
    xampp部署elgg
    转xampp 访问出现New XAMPP security concept
    FPGA参考电源
    android开发环境搭建问题
    cadence仿真前电路板设置(转)
    cadence串扰仿真 (转)
    cadence约束管理器总体设置 (转)
  • 原文地址:https://www.cnblogs.com/yang4869/p/10338703.html
Copyright © 2011-2022 走看看