最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • Python如何解决源代码与检查元素不一致的爬虫问题

    正文概述    2020-08-26   333

    Python如何解决源代码与检查元素不一致的爬虫问题

    针对源代码和检查元素不一致的网页爬虫——利用Selenium、PhantomJS、bs4爬取12306的列车途径站信息

    整个程序的核心难点在于上次豆瓣爬虫针对的是静态网页,源代码和检查元素内容相同;而在12306的查找搜索过程中,其网页发生变化(出现了查找到的数据),这个过程是动态的,使得我们在审查元素中能一一对应看到的表格数据没有显示在源代码中。这也是这次12306爬虫和上次豆瓣书单爬虫的最大不同点。

    选择使用Selenium的PhantomJS模拟浏览器爬取源代码,这样获取到的datas包含了我需要的(查找搜索出的)途径站数据。

    暂时把整个程序分为了这几个部分:

    (1)提取列车Code和No信息;

    (2)找到url规律,根据Code和No变化实现多个网页数据爬取;

    (3)使用PhantomJS模拟浏览器爬取源代码;

    (4)用bs4解析源代码,获取所需的途径站数据;

    (5)用csv库存储获得的数据。

    整体使用面向过程的书写方式。

    (1)values_get()函数实现了从已有存储了列车信息的csv中逐次提取Code和No。(在这里有点刻意追求面向过程的函数,设置了每次提取都openfile再close。所以使用了tell一次readline完的游标位置,再seek次游标位置到下一次提取位置,实现关闭file后仍然可以接着上一次结束的seek位置继续操作)

    (2)olddriver()函数包含PhantomJS和bs4两个部分。利用format来控制多个url,用PhantomJS、driver代替requests爬取网页源代码driver.get(url)。service_args可以配置模拟浏览器(优化加速),set_page_load_timeout()和set_script_timeout()+try except('window.stop()')设置超时(还未用上,存疑),最后用driver.quit()关闭使用完的PhantomJS避免内存爆炸。*这里存在很多优化模拟浏览器的方法,除了上述的配置、超时、quit,还包括在循环外提前打开PhantomJS来实现程序运行时间加速等方法,笔者还未理解透这些方法。这里贴出优化的参考链接:①https://blog.csdn.net/weixin_40284075/article/details/87190040②https://www.jianshu.com/p/8ec70859ae03还有PhantomJS的使用攻略①https://www.cnblogs.com/miqi1992/p/8093958.html②https://www.cnblogs.com/lizm166/p/8360388.html

    为什么使用已经被Selenium抛弃的PhantomJS而不使用Headless Chrome?笔者也曾尝试过使用无头chrome,但爬到的源代码仍不包含我所需tbody数据。

    丢失数据的源代码长这样(它只有tbody标签,没有标签内的数据)。

    Python如何解决源代码与检查元素不一致的爬虫问题

    而检查元素里可以看到所需数据出现在tbody内:

    Python如何解决源代码与检查元素不一致的爬虫问题

    虽然用PhantomJS确实可以爬取到所需的tbody数据,但是在后来循环url爬取多个列车信息时,可能是因为网站有反爬虫措施,或是PhantomJS的不稳定,导致了经常会出现丢失数据的情况(PhantomJS的作用失效了)。所以我添加了一句if datas==[],递归olddriver()来确保能爬到这班列车的信息。如图,失败率仍然很高。

    相关推荐:《Python视频教程》

    Python如何解决源代码与检查元素不一致的爬虫问题

    (3)最后是data_write_csv()写入数据到csv,这里用csv库直接把列表变为了csv文件(列表中的多个列表就是多行数据),以后多尝试用一下csv库,还是很好用的。

    (4)在主程序调用各个函数时,要注意global全局变量的使用、函数return参数给其他函数使用。

    (5)最后是几点自己的建议和猜想。首先如果12306真的有反爬虫,我们可以尝试像requests一样的伪装(在driver里没刻意伪装)或是换其他的网站来爬取。其次多注意:爬取网页查询搜索数据的方法,网页跳转等(或简易成爬取多个网页数据,如本例)。还有PhantomJS和headless Chrome,按理来说headless Chrome不会出现这样的错误。最后是提升爬虫运行速度的方法,(这次的爬取速度实在太慢了,10条信息平均要3分钟才能成功获得),除了对模拟浏览器的配置和优化,以及代码本身的优化(如file文件一直开着,不提取一次数据就开关file一次),我们是否可以尝试其他的源代码.get(url)获取方式?尝试多线程加速?尝试云服务器?

    代码:

      import urllib3
      #import requests
      from selenium import webdriver
      from bs4 import BeautifulSoup
      import csv
      import time
       
      start = time.time()
       
      def values_get():#通过设置游标来实现:从上一次结束的地方继续读取
          file = open('Code.csv','r')
          global seekloc#全局游标
          file.seek(seekloc)#设置游标位置
          line = file.readline()
          '''
          if line == '':
              break
          '''
          if line == '':
              seekloc = -1
          twovalue = line.strip('\n').split(',')#csv转化为list
          code, no = twovalue[0], twovalue[1]
          seekloc = file.tell()#读取结束时游标的位置
          file.close()
          return code, no#code是列车号,no是长串
      
      def olddriver():
      
          #下文中将PhantomJS移除循环未果,任选择在循环中打开。
          service_args=[]#PhantomJS优化
          service_args.append('--load-images=no')  ##关闭图片加载
          driver = webdriver.PhantomJS(service_args=service_args)
      
          driver.set_page_load_timeout(10)  # 设置页面加载超时
          driver.set_script_timeout(10)  # 设置页面异步js执行超时
          
          url = f'https://kyfw.12306.cn/otn/queryTrainInfo/init?train_no={no}&station_train_code={code}&date=2019-07-16'
          try:
              driver.get(url)
              data = driver.page_source
          except:
              print('Timeout!')
              driver.execute_script('window.stop()')
          driver.quit()#这句可让PhantomJS关闭
          #return data
      
      #def beauti4soup():
          #global data
          soup = BeautifulSoup(data,'lxml')
          table_datas = soup.find('table',{'id':'queryTable'})
          datas = table_datas.findAll('tbody')[1].findAll('tr')
          if datas == []:
              print('Failed... Restart!')
              olddriver()
              #beauti4soup()
          else:
              print("It's OK! ")
          midways = []
          for data in datas:
              midway = data.find('div',{'class':'t-station'}).get_text()#单个列车的信息爬取
              midways.append(midway)
          answer.append(midways)
          return answer
      
      def data_write_csv(file_name,datas):
          file_csv = open(file_name,'w+')
          #writer = csv.writer(file_csv,delimiter=',',quotechar=' ',quoting=csv.QUOTE_MINIMAL)csv库用法存疑
          writer = csv.writer(file_csv)
          for data in datas:
              writer.writerow(data)
      
      
      #---主程序开始---#
      
      seekloc = 0#初始化游标
      values_get()#运行一次values_get()把csv无用的第一行过滤掉
      answer = []#存储所有途径站信息的list
      '''
      #这里三行尝试将PhantomJS放在循环外,提前开启,减少加载时间。
      #结果:运行时间确实大幅减短,但遇到一次failed之后就一直failed。
      #参考链接:https://blog.csdn.net/qingwuh/article/details/81583801
      service_args=[]#PhantomJS优化
      service_args.append('--load-images=no')  ##关闭图片加载
      driver = webdriver.PhantomJS(service_args=service_args)
      '''
      j = 1
      while True:#循环爬取
          code, no = values_get()
          if j > 10:#十个一循环的测试
              break
          #if seekloc == -1:
          #    break
          answer = olddriver()
          j += 1 
      
      data_write_csv('Route.csv',answer)#存储数据 
      
      #---主程序结束---#
      end = time.time()
       print('Running time: {} Seconds'.format(end-start))
       print("=================================")

    起源地下载网 » Python如何解决源代码与检查元素不一致的爬虫问题

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元