首页 > 编程知识 正文

爬虫爬取百度检索数据,爬取百度首页

时间:2023-05-04 23:33:30 阅读:215227 作者:3347

(本文原作于2017年4月4日)

是这样的,在所谓的网络空间搜索引擎钟馗之眼搜索某cms名称,发现搜索结果只有可怜的17条,而在百度搜索“”Powered by 某cms””,结果有约2,150个,差距还是很大的。而去国外的那个俏皮的身影搜这个cms,结果直接为“No results found”。好吧,还得靠百度。

为便于程序自动化处理搜索结果,便产生了写一个Python脚本来自动搜索的想法。要求输入搜索关键词和页数,输出百度搜索此关键词所得结果的前某某页中的指向搜索结果的链接。

难点有二,一是百度搜索结果中的链接都不是直接指向搜索结果的,而是:

http://www.baidu.com/link?url=N5vu2VW2jp1E4lIDBiL77-J2B65YL9MgyXC0YmJNdjW

这种样子的,需要再处理才行。二是翻页问题,现在百度搜索结果的翻页不再由url中的参数pn来控制,在以前,pn=2便是搜索结果的第二页,pn=5便是搜索结果的第5页,现在不清楚是怎么控制翻页的,我研究也好久也没弄明白。

第一个问题的解决是这样的,先拿到会跳转的链接,然后打开它,会发现HTTP状态码是302,从HTTP头的location字段中便可以取到目标链接。第二个问题的解决是取巧的,每个爬取的页面总有下一页的按钮,直接解析出下一页的按钮对应的url,便拿到了下一页的url。

给这个脚本命名为baidu_crawler.py,有三个参数,-k是必须的,后接搜索关键词,-t后接一个整数,是超时时间,默认为60秒,-p后接一个整数,是要爬取的总页数,默认为5页。如在终端中输入如下命令:

python baidu_crawler.py -k inurl:asp?id= -p 2

其输出结果为:

http://www.newmen.com.cn/product/product.asp?id=664 http://fanyi.baidu.com/?aldtype=23&keyfrom=alading#en/zh/inurl%3Aasp%3Fid http://fanyi.baidu.com/?aldtype=23#en/zh/inurl%3Aasp%3Fid http://www.ampcn.com/show/index.asp?id=225238 http://www.jmzjzc.com/news.asp?id=1296 http://www.youda999.com/NewsView.Asp?ID=1818&SortID=10 http://www.kjcxpp.com/tebie.asp?id=4987 http://www.szxcc.com/gb/about1_xinxi.asp?id=325 http://www.synsun.com.cn/IntotheformerSt.asp?id=15 http://www.yorku.org.cn/displaynews1_new.asp?id=63 http://www.luoxin.cn/newsinfo.asp?id=8623 http://dfgjt.com/show_news.asp?id=515 http://jsxx.ahau.edu.cn/jsxx_show.asp?ID=1995046 http://www.fjplan.org/chgnr.asp?id=227 http://chem.xmu.edu.cn/show.asp?id=1995 http://www.nhzupei.com/viewanli.asp?id=556 http://www.snsafety.gov.cn/admin/pub_newsshow.asp?id=1040041&chid=100118 http://www.cnarts.net/cweb/news/read.asp?id=317959 http://www.zjgjgs.com/news_view.asp?id=964 http://www.sanheip.com/about.Asp?id=3 http://www.cqgbc.org/news_x.asp?id=403

下面是这个程序的源代码:

#!/usr/现实的服饰/python# ^_^ coding:utf8 ^_^import reimport requestsimport tracebackfrom urllib import quoteimport sys, getoptreload(sys)sys.setdefaultencoding('utf-8')class crawler: '''爬百度搜索结果的爬虫''' url = u'' urls = [] o_urls = [] html = '' total_pages = 5 current_page = 0 next_page_url = '' timeout = 60 #默认超时时间为60秒 headersParameters = { #发送HTTP请求时的HEAD信息,用于伪装为浏览器 'Connection': 'Keep-Alive', 'Accept': 'text/html, application/xhtml+xml, */*', 'Accept-Language': 'en-US,en;q=0.8,zh-苗条的夏天-CN;q=0.5,zh-苗条的夏天;q=0.3', 'Accept-Encoding': 'gzip, deflate', 'User-Agent': 'Mozilla/6.1 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko' } def __init__(self, keyword): self.url = u'https://www.baidu.com/baidu?wd='+quote(keyword)+'&tn=monline_dg&ie=utf-8' def set_timeout(self, time): '''设置超时时间,单位:秒''' try: self.timeout = int(time) except: pass def set_total_pages(self, num): '''设置总共要爬取的页数''' try: self.total_pages = int(num) except: pass def set_current_url(self, url): '''设置当前url''' self.url = url def switch_url(self): '''切换当前url为下一页的url 若下一页为空,则退出程序''' if self.next_page_url == '': sys.exit() else: self.set_current_url(self.next_page_url) def is_finish(self): '''判断是否爬取完毕''' if self.current_page >= self.total_pages: return True else: return False def get_html(self): '''爬取当前url所指页面的内容,保存到html中''' r = requests.get(self.url ,timeout=self.timeout, headers=self.headersParameters) if r.status_code==200: self.html = r.text self.current_page += 1 else: self.html = u'' print '[ERROR]',self.url,u'get此url返回的http状态码不是200' def get_urls(self): '''从当前html中解析出搜索结果的url,保存到o_urls''' o_urls = re.findall('href="(http://www.baidu.com/link?url=.*?)" class="c-showurl"', self.html) o_urls = list(set(o_urls)) #去重 self.o_urls = o_urls #取下一页地址 next = re.findall(' href="(/s?wd=[wd%&=_-]*?)" class="n"', self.html) if len(next) > 0: self.next_page_url = 'https://www.baidu.com'+next[-1] else: self.next_page_url = '' def get_real(self, o_url): '''获取重定向url指向的网址''' r = requests.get(o_url, allow_redirects = False) #禁止自动跳转 if r.status_code == 302: try: return r.headers['location'] #返回指向的地址 except: pass return o_url #返回源地址 def transformation(self): '''读取当前o_urls中的链接重定向的网址,并保存到urls中''' self.urls = [] for o_url in self.o_urls: self.urls.append(self.get_real(o_url)) def print_urls(self): '''输出当前urls中的url''' for url in self.urls: print url def print_o_urls(self): '''输出当前o_urls中的url''' for url in self.o_urls: print url def run(self): while(not self.is_finish()): c.get_html() c.get_urls() c.transformation() c.print_urls() c.switch_url()if __name__ == '__main__': help = 'baidu_crawler.py -k <keyword> [-t <timeout> -p <total pages>]' keyword = None timeout = None totalpages = None try: opts, args = getopt.getopt(sys.argv[1:], "hk:t:p:") except getopt.GetoptError: print(help) sys.exit(2) for opt, arg in opts: if opt == '-h': print(help) sys.exit() elif opt in ("-k", "--keyword"): keyword = arg elif opt in ("-t", "--timeout"): timeout = arg elif opt in ("-p", "--totalpages"): totalpages = arg if keyword == None: print(help) sys.exit() c = crawler(keyword) if timeout != None: c.set_timeout(timeout) if totalpages != None: c.set_total_pages(totalpages) c.run()

PS: 欢迎访问我的独立博客:若水斋 https://blog.werner.wiki/

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。