前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一次爬虫的编写尝试

一次爬虫的编写尝试

作者头像
程序员架构进阶
发布2021-10-11 10:29:12
2600
发布2021-10-11 10:29:12
举报
文章被收录于专栏:架构进阶架构进阶

一 背景

近期有想法,想要拿到指定时间段的新闻/文章信息,简单做个舆情分析。那么最基础的就是先获取文章列表。舆情相关的现成接口有一些,例如 微博的舆情监测平台,里面有比较成熟的api提供;阿里云,百度云也都有舆情接口。不过受限于某些因素,或是费用问题,或是api本身能提供的新闻时间范围不符合预期,导致无法直接使用。那么就考虑临时通过spider去抓取一些信息,用于支持本次的工作内容。

二 关于舆情检测

舆情监测,是指根据关键词获取舆情信息,包括新闻、论坛、博客、微博、微信、贴吧等。这里补一句,京东云的京东万象,发现是一个不错的api聚合入口。以舆情api为例,涵盖了多家服务:

各家服务提供方的能力实现,基本也是通过自己抓取和接口合作等方式收集新闻信息,做好渠道覆盖,然后再本地存储后进行舆情分析,并对外提供结果。说起来简单,但涉及检索、模型的部分还是有难度的。

三 信息来源

回归主题。我们要做的第一步是选择一个合适的数据来源,来收集文章。考虑到收集成本,直接用各家搜索引擎/流量平台是个不错的选择,因为作为流量入口,已经帮我们完成了各渠道资源收集的工作。

不过另一方面,各大流量平台都是爬虫起家,对于各种爬虫策略了如指掌,如果是大批量的抓取是比较容易被发现的。好在我们都只是少量,偶尔的获取信息,而且仅用于学习使用,并不会造成多大的流量影响,所以一般是不会被关注的。有底线,有分寸,真的很重要!

四 内容分析

4.1 搜索示例

正逢最近福建再起疫情,我们就先以这个作为关键词搜索:

结果对应的链接:

https://www.baidu.com/s?wd=%E7%A6%8F%E5%BB%BA%20%E7%96%AB%E6%83%85&rsv_spt=1&rsv_iqid=0xff465a7d00029162&issp=1&f=8&rsv_bp=1&rsv_idx=2&ie=utf-8&tn=baiduhome_pg&rsv_enter=1&rsv_dl=ib&rsv_sug3=28&rsv_sug1=19&rsv_sug7=101&rsv_sug2=0&rsv_btype=i&inputT=6747&rsv_sug4=11869

4.2 搜索结果内容分析

这里,我们重点分析网页结构,来确认解析方法。

下发的几条搜索结果,都是由:

1、标题(累计发现“6+18”,一文读懂福建疫情现状和传播链),

2、发布时间:(1天前),

3、内容摘要:【病例详情】莆田市累计发现6例确诊、18例无症状感染者 据莆田市疾控中心介绍,截至11日16时,此次疫情累计发现6例确诊、18例无症状感染者。福建新增1例本土确诊4例无症状,均为莆田市报告 9...

4、来源:新京报

组成,这些也是我们要收集的要素。

4.3 页面源码解析

我们页面查看源代码,定位到上面这条新闻的位置如下:

代码语言:javascript
复制
data-click="{

      'F':'778717EA',
      'F1':'9D73F1E4',
      'F2':'4CA6DE6B',
      'F3':'54E5263F',
      'T':'1631514840',
            'y':'FFF5FF4D'
                        }"
        href = "http://www.baidu.com/link?url=q7_vtPksHy_0aWRKZN8tfIsAl3bIFwiqMLAh1keliirFxhui2JPtcElwM4pvYz6_IOYVgaozLiQcXmFK4Gc9mT8i-dt3_6WdlXLeE10L0xO"

                target="_blank"
        
    >累计发现“6+18”,一文读懂<em>福建疫情</em>现状和传播链</a></h3><div class="c-row c-gap-top-small"><div class="general_image_pic c-span3" style="position:relative;top:2px;"><a class="c-img c-img3 c-img-radius-large" style="height:85px"
          href="http://www.baidu.com/link?url=q7_vtPksHy_0aWRKZN8tfIsAl3bIFwiqMLAh1keliirFxhui2JPtcElwM4pvYz6_IOYVgaozLiQcXmFK4Gc9mT8i-dt3_6WdlXLeE10L0xO"
                target="_blank"
      ><img class="c-img c-img3 c-img-radius-large" src="https://t10.baidu.com/it/u=2742646726,152697636&fm=30&app=106&f=JPEG?w=312&h=208&s=31B6E832CF9241E9146191EF00005021"  style="height:85px;" /><span class="c-img-border c-img-radius-large"></span></a></div><div class="c-span9 c-span-last"><div class="c-abstract"><span class=" newTimeFactor_before_abs c-color-gray2 m">1天前&nbsp;</span>【<em>病例</em>详情】莆田市累计发现6例<em>确诊</em>、18例无症状感染者 据莆田市疾控中心介绍,截至11日16时,此次<em>疫情</em>累计发现6例<em>确诊</em>、18例无症状感染者。<em>福建</em>新增1例本土<em>确诊</em>4例无症状,均为莆田市报告 9...</div><style>.user-avatar {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: flex-start;
}</style><div class="f13 c-gap-top-xsmall se_st_footer user-avatar"><a target="_blank" href="http://www.baidu.com/link?url=q7_vtPksHy_0aWRKZN8tfIsAl3bIFwiqMLAh1keliirFxhui2JPtcElwM4pvYz6_IOYVgaozLiQcXmFK4Gc9mT8i-dt3_6WdlXLeE10L0xO" class="c-showurl c-color-gray" style="text-decoration:none;position:relative;"><div class="c-img c-img-circle c-gap-right-xsmall" style="display: inline-block;width: 16px;height: 16px;position: relative;top: 3px;vertical-align:top;"><span class="c-img-border c-img-source-border c-img-radius-large"></span><img src="https://pic.rmb.bdstatic.com/9da74a517eb1befeba93a5f3167cc74b.jpeg"></div><style>.nor-src-icon-v {display: inline-block;width: 10px;height: 10px;border-radius: 100%;position: absolute;left: 7px;bottom: -1px;background-image: url(https://b.bdstatic.com/searchbox/icms/searchbox/img/yellow-v.png);background-size: 10px 10px;}
        .nor-src-icon-v.vicon-1 {background-image: url(https://b.bdstatic.com/searchbox/icms/searchbox/img/red-v.png);}
        .nor-src-icon-v.vicon-2 {background-image: url(https://b.bdstatic.com/searchbox/icms/searchbox/img/blue-v.png);}
        .nor-src-icon-v.vicon-3 {background-image: url(https://b.bdstatic.com/searchbox/icms/searchbox/img/yellow-v.png);}</style><span class="nor-src-icon-v vicon-2"></span>新京报</span></a><div class="c-tools c-gap-left" id="tools_11222397331129245369_10" data-tools='{"title":"累计发现“6+18”,一文读懂福建疫情现状和传播链","url":"http://www.baidu.com/link?url=q7_vtPksHy_0aWRKZN8tfIsAl3bIFwiqMLAh1keliirFxhui2JPtcElwM4pvYz6_IOYVgaozLiQcXmFK4Gc9mT8i-dt3_6WdlXLeE10L0xO"}'><i class="c-icon f13" >&#xe62b;</i></div><span class="c-icons-outer"><span class="c-icons-inner"></span></span><style>.snapshoot, .snapshoot:visited {
        color: #9195A3!important;
    }
    .snapshoot:active, .snapshoot:hover {
        color: #626675!important;
    }</style><a data-click="{'rsv_snapshot':'1'}" href="http://cache.baiducontent.com/c?m=3KZKMrJKhK1otETy33lbReLfsu2eWoaOfZYd2MNWUY3xbKNxMJNNwt_CsOHD6e7Qgf2Tu0GsMgHlSCO1_urn2_JjqYPGu6wMAk4gekije3KTYWOhsyDxmgTxtXJYJJMOij3XKVONqycqZ7hhjK7jNCazerlWVPWh5X0RiBQJlrbX68JcbomnhpiL-nT2Mc-T&p=882a930085cc43fd1cb9d1284e&newp=8b2a970d86cc47f719a28a285f53d836410eed643ac3864e1290c408d23f061d4863e1b923271101d5ce7f6606af4359e1f2337323454df6cc8a871d81edda&s=cfcd208495d565ef&user=baidu&fm=sc&query=%B8%A3%BD%A8+%D2%DF%C7%E9&qid=b3c763fd0003c0d6&p1=10"
                        target="_blank"
                    class="m c-gap-left c-color-gray kuaizhao snapshoot">百度快照</a></div></div></div></div>

接下来就是处理每个要素的前后标记,并通过对应的前后表情来截取所需的内容。

五 解析源码

5.1 user_agents设置

代码语言:javascript
复制
#设置多个user_agents,防止百度限制IP
user_agents = ['Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20130406 Firefox/23.0', \
    'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:18.0) Gecko/20100101 Firefox/18.0', \
    'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/533+ \
    (KHTML, like Gecko) Element Browser 5.0', \
    'IBM WebExplorer /v0.94', 'Galaxy/1.0 [en] (Mac OS X 10.5.6; U; en)', \
    'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)', \
    'Opera/9.80 (Windows NT 6.0) Presto/2.12.388 Version/12.14', \
    'Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) \
    Version/6.0 Mobile/10A5355d Safari/8536.25', \
    'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) \
    Chrome/28.0.1468.0 Safari/537.36', \
    'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.0; Trident/5.0; TheWorld)']
代码语言:javascript
复制
5.2 获取搜索结果的文件内容(html)

这里有一点,pn代表的是搜索结果的分页,每页的数量是10,所以传参需要是0,10,20,...,切记。

代码语言:javascript
复制
def baidu_search(keyword,pn):
  p= {'wd': keyword}
  res=urllib2.urlopen(("http://www.baidu.com/s?"+urllib.urlencode(p)+"&pn={0}&cl=3&rn=100").format(pn))
  html=res.read()
  return html

5.3 一些工具方法

代码语言:javascript
复制
def getList(regex,text):
  arr = []
  res = re.findall(regex, text)
  if res:
    for r in res:
      arr.append(r)
  return arr
def getMatch(regex,text):
  res = re.findall(regex, text)
  if res:
    return res[0]
  return ""
def clearTag(text):
  p = re.compile(u'<[^>]+>')
  retval = p.sub("",text)
  return retval
def write2File(path, content):
  f = open(path,'w')
  writer = csv.writer(f)
  writer.writerow(content)
  # 5. 关闭文件
  f.close()

5.4 解析规则及结果写入文件

代码语言:javascript
复制
def geturl(keyword):
  newsList = []
  f = open('result-'+keyword+'.csv','w')
  writer = csv.writer(f)

  for page in range(60):
    pn=page*10
    html = baidu_search(keyword,pn)
    print pn
    # write2File('搜索结果-'+str(pn)+'.html', html)
    time.sleep(2)
    content = unicode(html, 'utf-8','ignore')
    itemList = content.split('content_left')
    # # print html
    for item in itemList:
      if item.find('class=\"m c-gap-left c-color-gray')>=0:
        linkList = re.findall(r"newTimeFactor_before_abs(.+)font", item)
        for link in linkList:
          news_date = re.findall(r"span style=\"color: #9195A3;\">(.+)<\/span>&nbsp;-&nbsp;", link)
          title = re.findall(r"\"title\":\"(.+)\",\"url", link)
          url = re.findall(r"url\":\"(.+)\"}\'>", link)
          source = re.findall(r"class=\"c-showurl\">(.+)<\/span><div", link)
          cars = [title[0], news_date[0], source[0], url[0]]
          newsList.append(cars)
          print title[0]
          writer.writerow(cars)

    itemList = content.split('newTimeFactor_before_abs c-color-gray2')

    i = 0
    for link in itemList:
      if i == 0:
        i=i+1
        continue;
      if link.find('general_image_pic')>=0:
        # print link
        news_date = re.findall(r" m\">(.+)&nbsp;</span>", link)
        
        source = re.findall(r".jpeg\"><\/div>(.+)<\/span><\/a><div ", link)
        if len(source) <= 0:
          source = re.findall(r"<span class=\"nor-src-icon-v vicon-2\"><\/span>(.+)<\/span><\/a><div", link)
        title = re.findall(r"\"title\":\"(.+)\",\"url", link)
        
        url = re.findall(r"url\":\"(.+)\"}\'>", link)

        if len(source) > 0:
          cars = [title[0], news_date[0], source[0], url[0]]
          newsList.append(cars)
          print title[0]
          writer.writerow(cars)
        i=i+1

  # 5. 关闭文件
  f.close()
  time.sleep(5)

5.5 执行入口

代码语言:javascript
复制
if __name__=='__main__':
  arr = ['检索词1 1','检索词2 2']
  for keyword in arr:
  geturl(keyword)

六 总结

至此,一个尝试性的spider编写完毕。如果想获取更多代码或保持技术上的沟通交流,可以关注公众号【程序员架构进阶】获取。另外再啰嗦一句,一定是只学习使用,不可大批量执行等类似攻击的行为。共勉。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-09-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员架构进阶 微信公众号,前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一 背景
  • 二 关于舆情检测
  • 三 信息来源
  • 四 内容分析
    • 4.1 搜索示例
      • 4.2 搜索结果内容分析
        • 4.3 页面源码解析
        • 五 解析源码
          • 5.1 user_agents设置
            • 5.3 一些工具方法
              • 5.4 解析规则及结果写入文件
                • 5.5 执行入口
                • 六 总结
                相关产品与服务
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档