鱼C论坛

 找回密码
 立即注册
查看: 1699|回复: 13

[已解决]【#$%$@???】我也不知道怎么回事的爬虫程序

[复制链接]
发表于 2018-2-22 01:34:32 | 显示全部楼层 |阅读模式

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

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

x
我用程序爬取网页新闻需要翻页,爬取的网站的特点是如果翻到的页数大于最大页数就会一直显示最后一页,于是我想通过设置一个计数变量temp,如果一个网页爬取的新闻超过20条已经爬过,就判定已经至最后一页。

但写的代码一直有问题。。。

代码如下:
  1. #!/usr/bin/env python
  2. #--*-- coding: utf-8--*--
  3. from bs4 import BeautifulSoup
  4. import urllib2
  5. import urllib
  6. import re

  7. def open_url(url,page_num,viewstate):
  8.     print url
  9.     headers={'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.86 Safari/537.36'}
  10.     values={'__VIEWSTATE':viewstate,'__EVENTTARGET':'List1$AspNetPager1','__EVENTARGUMENT':page_num}
  11.     data = urllib.urlencode(values)
  12.     req=urllib2.Request(url,data,headers)
  13.     page=urllib2.urlopen(req)
  14.     html=page.read().decode('utf-8')
  15.     #f=open('a.txt','wb')
  16.     #f.write(html.encode('utf-8'))
  17.     html=html.encode('utf-8')
  18.     return html
  19.    
  20. def get_urls(html,page_num):
  21.     temp=0
  22.     soup0 = BeautifulSoup(html, 'html.parser')
  23.     if page_num==1:
  24.         soup_v=soup0.find('input',id='__VIEWSTATE')
  25.         viewstate=soup_v.get('value')
  26.     soup1=soup0.find('div',id='mright1')
  27.     soup=soup1.find_all('a')
  28.     for each in soup:
  29.         add=each.get('href')
  30.         try:
  31.             if add in adds or'/skhtmlnews/' not in add:
  32.                 temp=temp+1
  33.                 continue
  34.             else:
  35.                 adds.append(add)
  36.                 title=each.get_text(strip=True)
  37.                 titles.append(title)
  38.                 print add
  39.                 print title
  40.         except:
  41.             continue
  42.     print temp
  43.     return viewstate,temp

  44. adds=[]
  45. titles=[]
  46. url0='http://www.science-weekly.cn/MoreList.aspx?id='
  47. viewstate='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'

  48. for i in range(1,100):
  49.     try:
  50.         url=url0+str(i)
  51.         for j in range(1,10000):
  52.             try:
  53.                 html=open_url(url,j,viewstate)
  54.                 viewstate,temp=get_urls(html,j)
  55.                 print '======================='#此处只能输出一次?
  56.                 if temp>20:
  57.                     break
  58.             except:
  59.                 continue
  60.     except:
  61.         continue
复制代码


问题:我检查下来,语句print '======================='只输出了一次,但它的上一句执行了很多次,这是为什么?
最佳答案
2018-2-23 16:51:44
脑子 发表于 2018-2-23 11:41
整个程序只出现了一次,我发现不能进行temp大于20就break的操作,于是用print ‘======’插在中间看看,p ...

在你的geturl 函数加上global viewstate如下
def get_urls(html,page_num):
    global viewstate
也可以将viewstate换个名字(如:viewstate1),并给变量一个值
因为如果你的viewstate1没有赋值,第二次时,下面语句没有执行 ,就会直return viewstate1,就出出错
if page_num==1:
        soup_v=soup0.find('input',id='__VIEWSTATE')
        viewstate1=soup_v.get('value')
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-2-22 09:32:41 | 显示全部楼层
你的get_url中的for语句如下
for each in soup:
        add=each.get('href')
        try:
            if add in adds or'/skhtmlnews/' not in add:
                temp=temp+1
                continue
            else:
                adds.append(add)
                title=each.get_text(strip=True)
                titles.append(title)
                print add
                print title
        except:
            continue
    print temp
由于你的网页中的标题的内容有30条,所以会输出add和title总共60个,然后输出======,
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-2-22 11:51:50 | 显示全部楼层
lyjlyj 发表于 2018-2-22 09:32
你的get_url中的for语句如下
for each in soup:
        add=each.get('href')

但它在我的for循环里只输出了一次?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-2-22 13:11:19 | 显示全部楼层
脑子 发表于 2018-2-22 11:51
但它在我的for循环里只输出了一次?

你是说整个程序只出现一次?如果不是那应该是楼上说的,temp返回就大于20,break
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-2-22 13:19:32 | 显示全部楼层
脑子 发表于 2018-2-22 11:51
但它在我的for循环里只输出了一次?

你把截图发过来看一下,我看不懂你什么意思
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-2-23 11:31:20 | 显示全部楼层
mintaka 发表于 2018-2-22 13:11
你是说整个程序只出现一次?如果不是那应该是楼上说的,temp返回就大于20,break

是的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-2-23 11:41:17 | 显示全部楼层
lyjlyj 发表于 2018-2-22 13:19
你把截图发过来看一下,我看不懂你什么意思

整个程序只出现了一次,我发现不能进行temp大于20就break的操作,于是用print ‘======’插在中间看看,print整个程序只输出一次,也就是后面print后面的那几行temp的判断语句是没有执行的,这是为什么呢?

部分程序运行结果:
1.爬完第一页第一次输出‘======’:

  1. /skhtmlnews/2015/8/2973.html
  2. 科技创新引领全球竞争
  3. /skhtmlnews/2015/7/2943.html
  4. 僵尸肉:都是噱头惹的祸
  5. /skhtmlnews/2015/3/2828.html
  6. 向着新时期扬帆起航
  7. /skhtmlnews/2015/3/2790.html
  8. 科学被围攻,其实“很科学”
  9. 6
  10. =======================
  11. http://www.science-weekly.cn/MoreList.aspx?id=1
  12. /skhtmlnews/2015/1/2745.html
  13. 学术期刊付费模式需技术市场倒逼
  14. /skhtmlnews/2014/12/2708.html
复制代码

2.爬取后面的页面时没有输出‘==========’:
  1. 谁来监管学术不端?
  2. /skhtmlnews/2011/10/1474.html
  3. 二元经济导致“寒门难出贵子”
  4. /skhtmlnews/2011/8/1464.html
  5. 动车追尾与发展速度
  6. /skhtmlnews/2011/7/1447.html
  7. 科研诚信体系必须独立统一
  8. 8
  9. http://www.science-weekly.cn/MoreList.aspx?id=1
  10. /skhtmlnews/2011/6/1432.html
  11. 值得珍视的文化自觉
  12. /skhtmlnews/2011/5/1411.html
  13. 再议科学与民主
  14. /skhtmlnews/2011/4/1387.html
复制代码

3.temp大于20时没有break:
  1. 科学新闻:你科学吗?
  2. /skhtmlnews/2008/11/49.html
  3. 1978年:还原科学与科学还原
  4. /skhtmlnews/2008/11/3.html
  5. 转基因,科学传播和公共科学杂志
  6. 6
  7. http://www.science-weekly.cn/MoreList.aspx?id=1
  8. 32
  9. http://www.science-weekly.cn/MoreList.aspx?id=1
  10. 32
  11. http://www.science-weekly.cn/MoreList.aspx?id=1
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-2-23 12:39:52 | 显示全部楼层

会不会是有错误直接跳过了
ps:访问这个网站需要那个values值吗,我看了一下没找到,直接就爬到了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-2-23 16:12:40 | 显示全部楼层
mintaka 发表于 2018-2-23 12:39
会不会是有错误直接跳过了
ps:访问这个网站需要那个values值吗,我看了一下没找到,直接就爬到了

如果出错了的话,print‘====’的上一步是get_url()函数,这个函数return前的最后一个语句是print temp,输出结果时temp是执行了的,大概是说明前面没错?

不知道你说的values是不是viewstate,这个参数得来是用于翻页的,不然不能翻页只能停留在第一页。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-2-23 16:51:44 | 显示全部楼层    本楼为最佳答案   
脑子 发表于 2018-2-23 11:41
整个程序只出现了一次,我发现不能进行temp大于20就break的操作,于是用print ‘======’插在中间看看,p ...

在你的geturl 函数加上global viewstate如下
def get_urls(html,page_num):
    global viewstate
也可以将viewstate换个名字(如:viewstate1),并给变量一个值
因为如果你的viewstate1没有赋值,第二次时,下面语句没有执行 ,就会直return viewstate1,就出出错
if page_num==1:
        soup_v=soup0.find('input',id='__VIEWSTATE')
        viewstate1=soup_v.get('value')
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-2-23 17:32:22 | 显示全部楼层
lyjlyj 发表于 2018-2-23 16:51
在你的geturl 函数加上global viewstate如下
def get_urls(html,page_num):
    global viewstate

viewstate在原程序中是在主函数中定义了的,有初值,不会产生没有赋值的情况。

是不是有什么其他问题呢?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-2-23 19:20:40 | 显示全部楼层
脑子 发表于 2018-2-23 17:32
viewstate在原程序中是在主函数中定义了的,有初值,不会产生没有赋值的情况。

是不是有什么其他问题 ...

不是其他,就是这个问题
由于你在函数中的if条件语句中使用了viewstate,并且你没有声明是全局变量,所以python会认为你return viewstate使用的是if中的变量,当if语句没有执行时,viewstate没有赋值,你就return了一个没有赋值的变量,所以会出现异常
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-2-24 13:28:07 | 显示全部楼层
确实是这个问题,不定义全局的话会引发“local variable 'viewstate' referenced before assignment”这个错误
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-2-24 21:11:31 From FishC Mobile | 显示全部楼层
最后那个tmep哪里来的,值是多少,,定义的函数报错直接下一次循环,压根没有返回,这程序允许得卡死函数里print URL,,看你URL多长,想卡坏我电脑,哼
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-28 07:44

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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