赞
踩
在港校做RA期间,本周老师安排了爬取国内二手房的交易网站,我先调研对比了各平台,之后选取了房天下和贝壳的数据进行爬取
贝壳需要注册登录才能访问,房天下不需要
因课题保密的要求,数据和完整代码无法分享,如果有需要的朋友或老师可以联系我个人微信(liguopingHNU)进行定制化爬取数据
提示:以下是本篇文章正文内容,思路和代码可供参考
例如:https://bj.lianjia.com/ershoufang/101108567289.html
分为:三个部分
缺点:
以此为例:
https://beijing.anjuke.com/prop/view/A5183579374?from=filter&spread=commsearch_p&uniqid=pc5f27c655bde998.84281277&position=1&kwtype=filter&now_time=1596442197
分为:两个部分
[房天下])https://esf.fang.com/)
上面显示有16万套待售,但真实性存疑,我查阅此软件评价较差,存在数据造假的问题
本网站也没有已成交的房源信息,不够全面
感觉对房源的介绍极为敷衍随意,不如其他平台的仔细介绍,真实感较差
贝壳的二手房详情更为丰富,网页主体分为四个部分,:
贝壳网和链家是多名网友较为推崇的两个平台,经过查询,两个平台的数据相差不大,且都有在售和已成交的数据
而其他平台,网友评价较低,主要原因为数据造假,在本次查询中也出现此问题
链家和贝壳在房源数据方面,展示极为清晰,方便我们获知总成交数量,在详情页的介绍也明显比其他两个平台更加翔实,真实性,可靠性更高
和老师进一步讨论之后,我们最后选择了贝壳和房天下,爬取北京市 近两年的二手房的在售和已成交
本次需求是先将新闻的概览信息保存到EXCEL文件,最后格式如下
|标题|时间|报社|版面号|版面信息|文章描述|正文url|
因课题保密的要求,数据和完整代码无法分享,如果有需要的朋友或老师可以联系我个人微信(liguopingHNU)进行定制化爬取数据
在保存上述简要信息的时候,我便将正文的url保存进txt文件,方便后续直接读写txt进行正文爬取
这种设计模式我觉得是做到了不同模块的解耦,如果有朋友有更好的想法也可以和我交流
最后正文保存格式如下:
按照 关键词-报道报社 - 新闻标题-正文 保存
因课题保密的要求,数据和完整代码无法分享,如果有需要的朋友或老师可以联系我个人微信(liguopingHNU)进行定制化爬取数据
目标的url 为 :
http://www.apabi.com/pku/?pid=usp.advsearch&db=newspaper&cult=CN
除了pku 是不同机构或高校会改变这个字段,在检索查看的其他过程中,本url不变,完全使用Ajax的异步加载
给我们的自动化翻页,匹配信息,查询都带来了极大的挑战
我使用了request进行测试,发现没有办法获取到返回的信息,页面总是不相符,测试了好久,一直没有得到正确的内容
一筹莫展之际,我只能使用selenium就行匹配(但这也给后续的爬去埋下了一个巨大的坑)
查看网页源代码发现,请求之后,返回的是iframe,直接更新下面的搜索结果,我们需要的信息是在iframe里面去进行匹配,如果直接匹配页面的话,是匹配不到的
Selenium的好处是所见即所得,但是因为是模仿人的点击,速度极慢,而且书写代码时非常繁杂,点击选项时可能就是网页滑动了一下,便导致定位错误,无法匹配
以下是模拟点击页面的代码,可以看到匹配元素时非常麻烦
driver_path = r"G:\Daily_Life\Google_driver\chromedriver.exe" def config(head_keyword,con_keyword,office_key): url = "http://www.apabi.com/pku/?pid=usp.advsearch&db=newspaper&cult=CN" chrome_options = Options() chrome_options.add_argument('--headless') chrome_options.add_argument('--disable-gpu') try: driver = webdriver.Chrome(executable_path=driver_path,chrome_options=chrome_options) driver.get(url) time.sleep(1) webdriver.common.action_chains.ActionChains(driver) #保存详细信息结果 rows=[] #保存文章 arts = [] #报纸标题输入框 head_key = driver.find_element_by_xpath('.//div[@class="adh1"]/input') head_key.send_keys(head_keyword) #报纸内容关键词输入 con_keyword con_key = driver.find_element_by_xpath('.//div[@class="adh1"][2]/input') con_key.send_keys(con_keyword) time.sleep(1) #报社关键词 paper_office = driver.find_element_by_xpath('.//div[@class="adh1"][4]/input') paper_office.send_keys(office_key) time.sleep(1) #选择时间按钮 time_bt = driver.find_element_by_xpath('.//ul[@class="rq_one"][2]') time_btn =time_bt.find_element_by_tag_name('input') time_btn.click() #时间范围(开始时间和结束时间) select_pre_time = driver.find_element_by_xpath('.//ul[@class="rq_one"][2]/li[2]/span') pre_time = select_pre_time.find_element_by_tag_name('input') pre_time.send_keys(p_time) time.sleep(1) select_end_time = driver.find_element_by_xpath('.//ul[@class="rq_one"][2]/li[4]/span') end_time = select_end_time.find_element_by_tag_name('input') end_time.send_keys(e_time) #时间顺序排列 time_sort = driver.find_element_by_id('raddateasc') time_sort.click() #点击检索 sou = driver.find_element_by_id('btmSch') sou.click() time.sleep(1) # 切换到iframe中 # 获取 iframe 对象 iframe_elemnt = driver.find_element_by_id("ifrResult") driver.switch_to.frame(iframe_elemnt) time.sleep(1) flag = True; IsOne = False #print('flag1:',flag) #点击下一页 #在这里可以使用class搜索,因为没有上一页干扰,但之后,有了上一页干扰 try: #没有找到,代表搜索结果只有一页 next_page = driver.find_element_by_xpath('.//a[@class = "pageImp"]') except Exception: IsOne = True print('当前搜索结果只有一页') print('\n') if(IsOne): #如果只有一页 articles =driver.find_elements_by_xpath('.//div[@class="search_list_content m2"]') for article in articles: row={} art={} #取到a标签 a = article.find_element_by_class_name('title') title = a.text row['title'] = title #网址 c_url = a.get_attribute('href') art['title'] = title art['url']= c_url arts.append(art) c = article.find_element_by_class_name('comment').text JianGeFu ='/' #结构如 : 常州晚报 / 2016 -08 -15 / A08版 / 版面城事 微交通 #查找了所有/ 的位置 list=[i.start() for i in re.finditer('/', c)] if(len(list)>=3): #找到的每一个/ 的位置 l1 = list[0] l2 = list[1] l3 = list[2] c_comment = c[0:l1-5] c_office = c[l1-5:l1] c_time = c[l1+1:l2] c_ban_num = c[l2+1:l3] c_ban_name = c[l3+1:] else: c_comment = c[:-30] c_office = c[-29:25] c_time = c[-24:-8] c_ban_num = c[-7:-5] c_ban_name = c[-3:] print(title,'版面号有误') row['comment'] =c_comment row['office'] =c_office row['time'] =c_time row['ban_num'] =c_ban_num row['ban_name'] =c_ban_name rows.append(row) name = con_keyword+office_key pyexcel.save_as(records= rows,dest_file_name='%s.xls'%name) print('--------------------------------------------') print(name,'文章列表页的详细信息全部保存完毕') print('--------------------------------------------') #保存正文 for art in arts : filename= con_keyword+office_key+'url.txt' with open(filename, 'a', encoding='utf-8') as f: f.write(art['url']+'\n') f.close() print('--------------------------------------------') print(name,'文章的全文url全部保存完毕') print('--------------------------------------------') time.sleep(1)
在获取到返回信息之后,使用selenium就是不断的点击下一页,如果不存在下一页的按钮,那么不再翻页,开始保存。
对每一页的内容,有15篇报道,我发现他都是放在一个块里面的,可以通过遍历整个块来,获取每一篇的文章报道,并将它存到字典里面,最后将字典保存进数组,爬取完毕之后,打开excel将数组的写入
row={}
art={}
#标题
row['title'] = title
row['comment'] =c_comment
row['office'] =c_office
row['time'] =c_time
row['ban_num'] =c_ban_num
row['ban_name'] =c_ban_name
rows.append(row)
name = "我们赋予的文件名"
pyexcel.save_as(records= rows,dest_file_name='%s.xls'%name)
对于大规模的爬虫访问,我使用VPN测试了一下,发现差不多访问到2000次就会被block,这和我们要求的爬取量级远远不符,
使用selenium爬取太容易被墙,出现“检测到您的访问太过频繁的警告”。
常用的办法是使用代理IP,但是中华书苑会检测访问者的IP,如果不在IP范围之内(不属于高校),是无法正常访问的
解决不了被墙的问题,就先解决爬取速度吧
使用了多线程技术加快爬取速度,加上无头模式速度快了一点,但还是不能达到我们想要的速度
当时对于网络抓包分析这一块还不是很熟练的情况下,使用的又是非常坑爹的d(ŐдŐ๑)selenium,结果可想而知,只能看着它不断的把浏览器打开,然后关闭
为了快速爬取,后期只能找了十几个北大账号,加快爬取,往往是一个掉线之后,另一个立刻挂上
多线程的优点完全没有被体现出来
就这样爬了十多万篇之后,实在忍受不了,开始另谋他法
突然发现这个中华书院有一个注册的功能,在第一次登录之后,可以通过注册他的账号访问,不用特定的IP登录
刚发现这个的我欣喜不已,一晚上爬了四五万篇
但是这个bug很快被对方运维人员发现,将这个规则填补,直接把注册功能取消或无法进行注册
又一次山穷水尽之后
项目搁置了一个月
但师姐一直在催促,期间我还去旁边高校使用校园网(校园范围内IP随机变化),这种办法取爬取了一些,但是总是治标不治本
最后认认真真分析了整个网络协议流程和抓包的请求通信之后
我发现他返回的数据虽然庞杂,但是有三条比较核心,
headers = { 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8', 'Accept-Encoding': 'gzip, deflate', 'Accept-Language': 'zh-CN,zh;q=0.9', 'Cache-Control': 'max-age=0', 'Connection': 'keep-alive', 'Content-Length': '0', 'Content-Type': 'application/x-www-form-urlencoded', 'Cookie': '__cfduid=dac2c0020a2e072b6ba4fde90f45d91f81602924475; Hm_lvt_07cfb20d5f1d7402d600e55de80e9127=1602935685,1603206348,1603702503,1603727123; Hm_lvt_eaa57ca47dacb4ad4f5a257001a3457c=1602935697,1603206359,1603702506,1603727128; .ASPXANONYMOUS=_q9kIBfb1gEkAAAAMTY5ZDY0N2UtYmNhNi00NmViLTk0NzEtN2M4Yjg1MWFmNTI5IjVThVwuTPrCeki-rIt5Gstg2HE1; ASP.NET_SessionId=dl3ngom53i0mqvkd4fc0bnsw; ups_token=aXA6MTA2LjEyMC4xMjQuNDYsdW46LGVtYWlsOixvcmdpZDpwa3UsZW5kdGltZToyMDIwLTEwLTI3IDAxOjQ1OjE1LHRvcGljczo=; USPLOGINUSERCOOKIENAME=42DCF6A99B346AF43C59627FCE52E595; Hm_lpvt_07cfb20d5f1d7402d600e55de80e9127=1603727123; Hm_lpvt_eaa57ca47dacb4ad4f5a257001a3457c=1603727128', 'Host': 'www.apabi.com', 'Upgrade-Insecure-Requests': '1', 'User-Agent': user, } while self.url_queue.empty() == False: #print('开始爬取,当前队列是否为空',self.url_queue.empty()) url = self.url_queue.get() response = requests.get(url, headers=headers) e = etree.HTML(response.text) time.sleep(0.3) try: title = e.xpath('.//h2[@class ="bo"]/text()') title = str(title) title = title.replace("['","").replace("']","").replace("\\r\\n","").replace("\\r","").replace(u'\\u3000',u'').replace(u'?',u'').replace(u' ',u'') #print(title) s_time = e.xpath('.//li[@class="daxiao"]/text()') s_time=''.join(s_time) ban_author = s_time.replace("\r\n","").replace(" ","") si_time = str(re.findall(r'(\d{4}-\d{1,2}-\d{1,2})',s_time)) si_time = si_time.replace("['","").replace("']","") content = e.xpath('.//li[@id="zoom"]/p/text()') content = str(content) content = content.replace("['","").replace("']","").replace(u'\\u3000',u'').replace(u'\xa0', u'') except Exception: si_time = '' ban_author='无' content = '无' title = '无'
因课题保密的要求,数据和完整代码无法分享,如果有需要的朋友或老师可以联系我个人微信(liguopingHNU)进行定制化爬取数据
很久之后老师聊了聊之后,建议可以使用异步的高性能网络请求包和高性能的线程,代替现在的request和Thread,但是本爬虫的ip检测阻止了我提升代码性能的欲望
严禁使用本代码恶意爬取数据库,造成严重后果自负
因课题保密的要求,数据和代码无法分享,如果有需要的朋友或老师可以联系我个人微信(liguopingHNU)进行定制化爬取数据
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。