鱼C论坛

 找回密码
 立即注册
查看: 1092|回复: 10

为什么爬取百度百科的时候会出现错误

[复制链接]
发表于 2018-9-24 00:02:25 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 RIXO 于 2018-9-24 09:40 编辑

呃,看书籍编的一个爬百度百科的代码,本来没有爬取成功,但是我在git上面看到一个爬取成功的,怀着好奇的心理就下载了,结果他的代码能用。。。。。
看了一下,发现在爬百度百科的时候,他使用的是urllib.request.urlopen(url)连header都没有加,但是能爬
结果我的用requests库,就会出现requests.exceptions.TooManyRedirects: Exceeded 30 redirects. 这个错误
求个解答!
呃,贴代码
  1. import requests
  2. import urlparse2,re,html_codec
  3. from bs4 import BeautifulSoup


  4. class UrlManager():
  5.     def __init__(self):
  6.         self.new_urls = set()
  7.         self.old_urls = set()

  8.     def has_new_url(self):      #是否有待获取的url
  9.         return self.new_url_size != 0

  10.     def get_new_url(self):       #获取一个新的url
  11.         new_url = self.new_urls.pop()
  12.         self.old_urls.add(new_url)
  13.         return new_url

  14.     def add_new_url(self,url):    #加入新的url
  15.         if url is None:
  16.             return
  17.         if url not in self.new_urls and url not in self.old_urls:
  18.             self.new_urls.add(url)

  19.     def add_new_urls(self,urls):
  20.         if urls is None or len(urls) == 0:
  21.             return
  22.         for url in urls:
  23.             self.add_new_urls(url)

  24.     def new_url_size(self):      
  25.         return len(self.new_urls)

  26.     def old_url_size(self):      
  27.         return len(self.old_urls)

  28. class HtmlDownloader():        #返回html内容
  29.     def download(self,url):
  30.         if url is None:
  31.             return None
  32.         headers = {
  33.         'Host' : 'baike.baidu.com',
  34.         'User_Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.84 Safari/537.36',
  35.         'Upgrade-Insecure-Requests': '1'
  36.         }
  37.         r = requests.get(url,headers = headers,allow_redirects=False)
  38.         if r.status_code == 200:
  39.             r,encoding = 'utf-8'
  40.             return r.text
  41.         return None

  42. class HtmlParser():         
  43.     def parser(self,page_url,html_cont):
  44.         if page_url is None or html_cont is None :
  45.             return
  46.         soup = BeautifulSoup(html_cont,'html.parser',from_encoding='utf-8')
  47.         new_urls = self._get_new_urls(page_url,soup)
  48.         new_data = self._get_new_data(page_url,soup)

  49.     def _get_new_urls(self,page_url,soup):     #解析出url
  50.         new_urls = set()
  51.         links = soup.find_all('a',href = re.compile(r'/view/\d+\.htm'))
  52.         for link in links:
  53.             new_url = link('href')
  54.             new_full_url = urlparse2.urljoin(page_url,new_url)
  55.             new_urls.add(new_full_url)
  56.         return new_urls

  57.     def _get_new_data(self,page_url,soup):     #解析出数据
  58.         data = {}
  59.         data['url'] = page_url
  60.         title = soup.find('dd',class_ = 'lemmaWgt-lemmaTitle-title').find('h1')
  61.         data['title'] = title.get_text()
  62.         summary = soup.find('div',class_ = 'lemma-summary' )
  63.         data['summary'] = summary.get_text()
  64.         return data

  65. class DataOutput():
  66.     def __init__(self):
  67.         self.datas = []

  68.     def store_data(self,data):
  69.         if data is None:
  70.             return
  71.         self.datas.append(data)

  72.     def output_html(self):
  73.         fout = html_codec.open('baike.html','w',encoding = 'utf-8')
  74.         fout.write('<html>')
  75.         fout.write('<body>')
  76.         fout.write('<table>')
  77.         for data in self.datas:
  78.             fout.wite('<tr>')
  79.             fout.write('<td>%s</td>'%data['url'])
  80.             fout.write('<td>%s</td>'%data['title'])
  81.             fout.write('<td>%s</td>'%data['summary'])
  82.             fout.write('</tr>')
  83.             self.datas.remove(data)
  84.         fout.write('</table>')
  85.         fout.write('</body>')
  86.         fout.write('</html>')
  87.         fout.close()
  88.         


  89. class SpiderMan():
  90.     def __init__(self):
  91.         self.manager = UrlManager()
  92.         self.downloader = HtmlDownloader()
  93.         self.parser = HtmlParser()
  94.         self.output = DataOutput()

  95.     def craw(self,root_url):
  96.         self.manager.add_new_url(root_url)
  97.         while (self.manager.has_new_url() and self.manager.old_url_size()<1):
  98.             #try:
  99.             new_url = self.manager.get_new_url()
  100.             html = self.downloader.download(new_url)
  101.             new_urls,data = self.parser.parser(new_url,html)
  102.             self.manager.add_new_urls(new_urls)
  103.             self.output.store_data(data)
  104.             print('已经抓取了%s个链接'%self.manager.old_url_size())
  105.             #except Exception as e:
  106.              #   print('crawl failed',e)

  107.         self.output.output_html()

  108. if __name__ == '__main__':
  109.     spider_man = SpiderMan()
  110.     spider_man.craw('https://baike.baidu.com/item/%E7%BD%91%E7%BB%9C%E7%88%AC%E8%99%AB')
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2018-9-24 07:45:07 | 显示全部楼层
代码呢
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-9-24 08:52:52 | 显示全部楼层
测试采集网址:https://baike.baidu.com/vbaike/
测试结果:
QQ截图20180924085159.jpg
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-9-24 09:40:26 | 显示全部楼层

呃,贴上了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-9-24 10:04:50 | 显示全部楼层
fout.wite('<tr>')拼写
parse2和html_codec库没装,也没用过= =
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-9-24 10:08:37 | 显示全部楼层
塔利班 发表于 2018-9-24 10:04
fout.wite('')拼写
parse2和html_codec库没装,也没用过= =

我也没用过,抄的代码,hhh,问题还没到那里呢,在htmldownload的模块那里就出问题了
那里用requests库获取网址的时候会出现链接超出的情况
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-9-24 10:08:57 | 显示全部楼层
安装了库运行也是各种错误= =
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-9-24 10:10:40 | 显示全部楼层
一般说的超链接超出都是cookies没维持住,你用session试试
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-9-24 10:13:03 | 显示全部楼层
本帖最后由 RIXO 于 2018-9-24 10:16 编辑
塔利班 发表于 2018-9-24 10:08
安装了库运行也是各种错误= =


再给你看看git上面找到的。
  1. # coding:utf8

  2. class UrlManager(object):
  3.     def __init__(self):
  4.         self.new_urls = set()
  5.         self.old_urls = set()
  6.    
  7.     def add_new_url(self,url):  #向管理器中添加一个新的url
  8.         if url is None:
  9.             return
  10.         if url not in self.new_urls and url not in self.old_urls:
  11.             self.new_urls.add(url)
  12.    
  13.    
  14.     def add_new_urls(self,urls): #向管理器中添加批量的url
  15.         if urls is None or len(urls) == 0:
  16.             return
  17.         for url in urls:
  18.             self.add_new_url(url)
  19.    
  20.    
  21.     def has_new_url(self):  #判断管理器中是否有新的待爬取的url
  22.         return len(self.new_urls) != 0

  23.    
  24.     def get_new_url(self):  #从url管理器中获取一个新的待爬取的url
  25.         new_url = self.new_urls.pop()
  26.         self.old_urls.add(new_url)
  27.         return new_url

  28. # coding:utf8
  29. import requests

  30. class HtmlDownloader(object):
  31.    
  32.    
  33.     def download(self, url):
  34.         if url is None:
  35.             return None

  36.         response = requests.get(url)
  37.         #response = urllib.request.urlopen(url)
  38.         #equest = urllib.request.Request(url)
  39.         #response = urllib.request.urlopen(request,context = context)
  40.         
  41.         if response.getcode() != 200:
  42.             return None
  43.         
  44.         return response.read()
  45.     # coding:utf8
  46. from bs4 import BeautifulSoup
  47. import re
  48. import urllib.request

  49. class HtmlParser(object):
  50.    
  51.    
  52.     def _get_new_urls(self, page_url, soup):
  53.         new_urls = set()
  54.         # /item/%E8%AE...  或    /item/GPL  
  55.         links = soup.find_all('a', href=re.compile(r"/item/.*"))
  56.         for link in links:
  57.             new_url = link['href']
  58.             new_full_url = urllib.parse.urljoin(page_url,new_url)
  59.             new_urls.add(new_full_url)
  60.         return new_urls
  61.    
  62.     def _get_new_data(self, page_url, soup):
  63.         res_data = {}
  64.         
  65.         #url
  66.         res_data['url'] = page_url
  67.         
  68.         # <dd class="lemmaWgt-lemmaTitle-title"> <h1>Python</h1>
  69.         title_node = soup.find('dd', class_="lemmaWgt-lemmaTitle-title").find("h1")
  70.         res_data['title'] = title_node.get_text()
  71.         
  72.         # <div class="lemma-summary" label-module="lemmaSummary">
  73.         summary_node = soup.find('div', class_="lemma-summary")
  74.         res_data['summary'] = summary_node.get_text()
  75.         
  76.         return res_data
  77.    
  78.     def parse(self,page_url,html_cont):
  79.         if page_url is None or html_cont is None:
  80.             return
  81.         
  82.         soup = BeautifulSoup(html_cont,'html.parser',from_encoding='utf-8')
  83.         new_urls = self._get_new_urls(page_url,soup)
  84.         new_data = self._get_new_data(page_url,soup)
  85.         return new_urls,new_data


  86. # coding:utf8
  87. import os
  88. class HtmlOutputer(object):
  89.     def __init__(self):
  90.         self.datas = []
  91.         
  92.    
  93.     def collect_data(self,data):
  94.         if data is None:
  95.             return
  96.         self.datas.append(data)

  97.    
  98.     def output_html(self):
  99.         fout = open('output.html', 'w', encoding='utf-8')

  100.         
  101.         fout.write("<html>")
  102.         fout.write("<body>")
  103.         fout.write("<table>")
  104.         
  105.         # python默认编码:ascii,这里要改成utf-8
  106.         for data in self.datas:
  107.             fout.write("<tr>")
  108.             fout.write("<td>%s</td>" %data['url'])
  109.             fout.write("<td>%s</td>" %data['title'])
  110.             fout.write("<td>%s</td>" %data['summary'])
  111.             fout.write("</tr>")
  112.         
  113.         fout.write("</table>")
  114.         fout.write("</body>")
  115.         fout.write("</html>")
  116.         
  117.         fout.close()
  118.     # coding:utf8
  119. import url_manager, html_downloader, html_parser,html_outputer,os

  120. class SpiderMain(object):
  121.     def __init__(self):
  122.         self.urls = url_manager.UrlManager()
  123.         self.downloader = html_downloader.HtmlDownloader()
  124.         self.parser = html_parser.HtmlParser()
  125.         self.outputer = html_outputer.HtmlOutputer()
  126.    
  127.     def craw(self, root_url):
  128.         count = 1
  129.         self.urls.add_new_url(root_url)
  130.         while self.urls.has_new_url():
  131.             #try:
  132.                 new_url = self.urls.get_new_url()
  133.                 print ('craw %d : %s' % (count, new_url))
  134.                 html_cont = self.downloader.download(new_url)
  135.                 new_urls,new_data = self.parser.parse(new_url,html_cont)
  136.                 self.urls.add_new_urls(new_urls)
  137.                 self.outputer.collect_data(new_data)
  138.                 print(os.getcwd())
  139.                
  140.                 if count == 1000:
  141.                     break
  142.                 count = count + 1
  143.             #except Exception as r:
  144.                 #print ('craw failed',r)
  145.             
  146.         self.outputer.output_html()



  147. if __name__=="__main__":
  148.     # http://baike.baidu.com/view/21087.htm 或  https://baike.baidu.com/item/Python/407313
  149.     root_url = "http://baike.baidu.com/view/21087.htm"
  150.     obj_spider = SpiderMain()
  151.     obj_spider.craw(root_url)
  152.     print('finish')
复制代码


这个和我从书上抄的差不多,但区别在于,他下载网页的时候用urlopen干的,就能下(我在那里改成了requests然后就不能了),由于是从多个文件里面复制过来的,有些多余的语句可以删掉
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-9-24 10:18:44 | 显示全部楼层
塔利班 发表于 2018-9-24 10:10
一般说的超链接超出都是cookies没维持住,你用session试试

session试过了,出现了一样的问题,但是他用urlopen能用,就是比较慢,我都先百度了一遍问题解决,然后再来搞的,最近发现问题在百度上面都找不到相同的,有点绝望
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-9-24 10:18:47 | 显示全部楼层
不看了,爬虫我是菜鸡
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2026-1-2 10:33

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表