目标网站

遇到的坑

这个网站为了反爬虫,使用了很多策略,而这些策略都会是爬虫中可能遇到的坑。

目的: 目的是爬取这个网页中的这个状态的项目(projectStatus=6)(估计是表示结束了的意思

坑1

  • 坑: 上面的图示网页,无法直接获得具体的项目的网页链接: 页面的地址是被动态加载的。也就是说没办法直接获取到每个项目的具体链接。
  • 解决方式: 这个是被我后面用一个方法(selenium)一起解决了,但其实不是一定要用selenium的。但是如果是只有这一个问题的话,我们其实一方面可以通过后台来看network相关的请求,另一方面看js的过程。

坑2

  • 坑: 在每一个项目页面中,加载到具体的具体信息页面中。采用的是js自动替换页面的技术。同样是这个原因,让我更想使用selenium来实现爬取了
  • 解决方式: selenium动态模拟

坑3

  • 坑:在具体的数据页面中数据的变换。 比如说到稍微到后面的一点点的页面的情况的哈,会发现网页的数据内容变了。

    • 比如说,有些是:最高可投,有些是每人限投。其实本质上是一个意思。
    • "标的公司", "项目公司"也是一样的道理
    • "标的估值", "项目公司估值"
    • 然后一开始的数据表示的话,中间是用中文输入法的),但是,在后面有些网页就会是: (英文输入法的冒号加上空格作为分隔符)
  • 解决办法: 全都是用中文的来进行字符串替代。

坑4

  • 坑:一开始的数据都是用每行用<p>来表示的,但是后来发现,会随机在某两种数据直接,使用<br>(换行符来分隔)。这样,如果采用一般的直接获取p标签的话,就会出现bug。导致会在某些地方一直没捕捉到数据。
  • 解决办法: 就是下面的代码段。要先获取具体的html代码然后根据html的结构进行分析。隐含的坑!!(find_…之类的话,如果是不存在的话,就会报错。但是之前说了这个是随机的…所以只能是使用try来实现)
tempDatas = []for d in datas:try:td = d.find_element_by_tag_name('span').get_attribute("innerHTML")if '<br>' in td:tds = td.split('<br>')for tdi in tds:tempDatas.append(tdi.replace('\n', '').replace('&nbsp;', ' ').replace(': ', ':').replace(':', ":").strip())else:tempDatas.append(d.text.strip().replace('\n', '').replace(': ', ':').replace(':', ":"))except Exception as e:tempDatas.append(d.text.strip().replace('\n', '').replace(': ', ':').replace(':', ":"))datas = tempDatas

坑5

  • 坑:网页结构发生了变化。 以前的数据似乎跟稍微近一些的数据不太一样。比如说关于我们想要的数据的所在的定位span。以前是第一个,但是后面的时候会遇到有些是在第二个上,所以就会出现一直爬不到信息的情况。
  • 解决办法: 这里的解决办法其实还不够完善,但是至少够用了。就是使用最后一个。我发现,之前的只有一个span的情况,那还是一样,但是有两个span的时候,数据一般是在后面的span中。所以我就直接使用了[-1]这样的方式来进行索引。

坑6

  • 坑:每次都要手动登录。非常麻烦,因为这里有需要有验证码,而且,验证码还是需要先手动先滑动一个东西之后,才会发到手机上的。而且,发到之后,每个手机号,每天只能发5次。这个非常坑。
  • 解决方法: 使用pickle来存储cookies。然后每次只用调用一次,以后的,就需要先访问登录网页,然后加载cookies就好了。根据我的实验,每一份cookies可以使用一天,然后,对面的这个网站,就会刷新这个cookies

具体的代码片段:

  • refresh 表示是否刷新cookies
if refresh:browser.get(LOGIN_URL)# 登录time.sleep(2)input = browser.find_element_by_xpath('//input[@placeholder="请输入手机号"]')input.send_keys(USERNAME)time.sleep(40)pickle.dump(browser.get_cookies(), open("cookies.pkl", "wb"))print('finish refresh')browser.get(tempURL)  # 加载网页time.sleep(2)
else:browser.get(LOGIN_URL)  # 加载网页cookies = pickle.load(open("cookies.pkl", "rb"))for cookie in cookies:browser.add_cookie(cookie)browser.get(tempURL)  # 加载网页time.sleep(2)

坑7

  • 坑:有些是有项目的价值,有些是有项目公司的价值,有些是两者都有 这个我惊呆了。
  • 解决方法: 我就想到用字典来存储,如果有就添加进去,否则就添加一个NULL。

坑8

  • 坑:这个网页有些神奇(或许是服务器质量不是很好),有些时候网页加载数据的速度很慢。(加载的延时很高)。有时候,爬取到了具体的数据,但是却没爬到对应的公司名字。这个没办法了。
  • 解决办法: 我就设置,如果当公司名字为空的话,就重新加载。然后最多重新加载一定的次数。

类似的有切换网页的时候也会出现失败,但是刷新一下也就好了。这个我就限制了,到了一定次数就直接终止整个程序。因为,我有天晚上爬取,但是半夜的时候断网了… 发现一直在爬取空数据。所以就有了这样的设计。

同时,我也增加了等待机制。 类似于下面的这种。

elemnt = WebDriverWait(browser, 10).until(EC.presence_of_element_located((By.XPATH, '//*[@id="__layout"]/div/div[2]/div/div[3]/ul/li[%d]/div/div/div[1]/div[2]/h3' % (index_i + 1))))

同样是因为那次停电,我之前爬取到不少有用的数据,但是没保存,所以我加入了一个中途定次数记录的代码。来保持中间的数据,为避免突然发生的问题。

坑9

  • 到很久远的数据时候,会发现没有数据了,全都是图片来表示数据
  • 这是我一个没解决的问题: 在图片内… 我大概就爬了300多条稍微干净的数据了,我想应该够用了吧。
  • 在图片内嵌入数据,这个只能做图片文字提取的技术了。。

代码如何使用

  • pageCount 第几页(是最开始的图片所示)
  • index_i在第几页的第几个(从0开始计数)

用这个可以做分段爬取(有时候遇到问题了,对于某些部分可以用这个来设置重新开始)

  • refresh = False 为True的时候,需要手动登录。然后,等待出现刷新完成之后就说明已经保存好cookies了。然后以后再启动的时候,就设置为False。这样就不需要再登录了。

  • configure 这个部分的代码,一般人都需要注释掉。我有这个代码,主要是因为我的chrome是我用源码替换掉的。所以没写入到系统中。然后就手动写执行文件所在的地址好了。一般人是不需要这段代码的。记得注释掉!!!

  • 下载好需要的库~

之后直接运行就好了。用时蛮久的。

完全的代码

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
import pickle
import pandas as pd#####################
USERNAME = "写自己的手机号码"
# 填写好账号 密码 下面的url根据要求替换掉
URL = "https://www.duocaitou.com/project?projectStatus=6&pageNum=%d"
pageCount = 1
tempURL = URL % pageCount
LOGIN_URL = "https://www.duocaitou.com/login?redirect=%2Fproject"
refresh = False#####################
# configure
options = webdriver.ChromeOptions()
options.binary_location = r"D:\Software\Chrome\Application\chrome.exe"
browser = webdriver.Chrome(chrome_options=options)keys = ['项目公司', '项目公司估值', '项目估值', '筹集规模', '筹集模式', '起投金额', '每人限投', '投资期限']
globalData = {}
for k in keys:globalData[k] = []if refresh:browser.get(LOGIN_URL)# 登录time.sleep(2)input = browser.find_element_by_xpath('//input[@placeholder="请输入手机号"]')input.send_keys(USERNAME)time.sleep(40)pickle.dump(browser.get_cookies(), open("cookies.pkl", "wb"))print('finish refresh')browser.get(tempURL)  # 加载网页time.sleep(2)
else:browser.get(LOGIN_URL)  # 加载网页cookies = pickle.load(open("cookies.pkl", "rb"))for cookie in cookies:browser.add_cookie(cookie)browser.get(tempURL)  # 加载网页time.sleep(2)print(tempURL)
save = 0
times = 0index_i = 0
continuetime = 0try:while True:try:elemnt = WebDriverWait(browser, 10).until(EC.presence_of_element_located((By.XPATH, '//*[@id="__layout"]/div/div[2]/div/div[3]/ul/li[%d]/div/div/div[1]/div[2]/h3' % (index_i + 1))))li_list = browser.find_element_by_xpath('//*[@id="__layout"]/div/div[2]/div/div[3]/ul/li[%d]/div/div/div[1]/div[2]/h3' % (index_i + 1)).click()elemnt = WebDriverWait(browser, 10).until(EC.presence_of_element_located((By.XPATH, '//*[@id="__layout"]/div/div[2]/div/div[1]/div[1]/div[2]/div[1]/div/div/div/div/div[3]')))browser.find_element_by_xpath('//*[@id="__layout"]/div/div[2]/div/div[1]/div[1]/div[2]/div[1]/div/div/div/div/div[3]').click()elemnt = WebDriverWait(browser, 10).until(EC.presence_of_element_located((By.XPATH, '//*[@id="__layout"]/div/div[2]/div/div[1]/div[1]/div[2]/div[2]/div[2]/div/span')))datas = browser.find_elements_by_xpath('//*[@id="__layout"]/div/div[2]/div/div[1]/div[1]/div[2]/div[2]/div[2]/div/span')if "筹集模式" in datas[0].text:datas = datas[0]else:datas = datas[-1]elemnt = WebDriverWait(datas, 10).until(EC.presence_of_element_located((By.TAG_NAME, 'p')))time.sleep(5 + continuetime)datas = datas.find_elements_by_tag_name('p')[0:40]except Exception as e:browser.get(tempURL)  # 加载网页print('refresh', tempURL, 'index is', index_i)time.sleep(5)continuetime += 1if continuetime >= 10:breakcontinuedatas = [d for d in datas if len(d.text.strip()) > 4 and (':' in d.text or ':' in d.text)][:8]tempDatas = []for d in datas:try:td = d.find_element_by_tag_name('span').get_attribute("innerHTML")if '<br>' in td:tds = td.split('<br>')for tdi in tds:tempDatas.append(tdi.replace('\n', '').replace('&nbsp;', ' ').replace(': ', ':').replace(':', ":").strip())else:tempDatas.append(d.text.strip().replace('\n', '').replace(': ', ':').replace(':', ":"))except Exception as e:tempDatas.append(d.text.strip().replace('\n', '').replace(': ', ':').replace(':', ":"))datas = tempDatastry:tempdict = {}for d in datas:if ':' not in d:continuea = d[:d.index(':')]b = d[d.index(':') + 1:]if a == '最高可投':a = '每人限投'a = a.replace("标的公司", "项目公司").replace("标的估值", "项目公司估值")if a in tempdict:if '筹集规模:' in b:b = b.split('筹集规模:')tempdict['项目公司估值'] = b[0]tempdict['筹集规模'] = b[1]else:tempdict['项目公司估值'] = belif a == '筹集模式' and '每人限投:' in b:b = b.split('每人限投:')tempdict[a] = b[0]tempdict['每人限投'] = b[1]elif a == '项目公司' and '筹集规模:' in b:b = b.split('筹集规模:')tempdict['项目公司估值'] = b[0]tempdict['筹集规模'] = b[1]else:tempdict[a] = bif len(tempdict) == 0 or '项目公司' not in tempdict:continuetime += 1if continuetime < 3:browser.get(tempURL)  # 加载网页time.sleep(2)continueelse:continuetime = 0for key in globalData.keys():if key in tempdict:globalData[key].append(tempdict[key])elif key == '标的公司':globalData['项目公司'].append(tempdict[key])elif key == '标的公司估值':globalData['项目公司估值'].append(tempdict[key])else:globalData[key].append('NULL')print(key, ': ', globalData[key][-1], end=' , ')print()times += 1if times % 50 == 49:pd.DataFrame(globalData).to_excel('data_%d.xlsx' % save, columns=keys)save += 1times = 0except Exception as e:print(e.args)for i, d in enumerate(datas):print(i, d)breakif index_i == 8:index_i = 0pageCount += 1if pageCount >= 67:breaktempURL = URL % pageCountprint(tempURL)browser.get(tempURL)  # 加载网页time.sleep(2)else:browser.get(tempURL)  # 加载网页time.sleep(2)index_i += 1continuetime = 0
finally:pd.DataFrame(globalData).to_excel('data.xlsx', columns=keys)

多彩投网站动态爬取[python+selenium]相关推荐

  1. python爬取js动态网页_Python 从零开始爬虫(八)——动态爬取解决方案 之 selenium

    selenium--自动化测试工具,专门为Web应用程序编写的一个验收测试工具,测试其兼容性,功能什么的.然而让虫师们垂涎的并不是以上的种种,而是其通过驱动浏览器获得的解析JavaScript的能力. ...

  2. python爬虫--Scrapy框架--Scrapy+selenium实现动态爬取

    python爬虫–Scrapy框架–Scrapy+selenium实现动态爬取 前言 本文基于数据分析竞赛爬虫阶段,对使用scrapy + selenium进行政策文本爬虫进行记录.用于个人爬虫学习记 ...

  3. 利用python爬虫技术动态爬取地理空间数据云中的元数据(selenium)

    python爬取地理空间数据云selenium动态点击 爬取的网址秀一下: 爬取的信息是什么呢? 这个信息的爬取涉及到右边按钮的点击,这属于动态爬取的范畴,需要用到selenium 好了,那么开始写代 ...

  4. 基于python的数据爬取与分析_基于Python的网站数据爬取与分析的技术实现策略

    欧阳元东 摘要:Python为网页数据爬取和数据分析提供了很多工具包.基于Python的BeautifulSoup可以快速高效地爬取网站数据,Pandas工具能方便灵活地清洗分析数据,调用Python ...

  5. UN Comtrade(联合国商品贸易统计数据库)数据爬取Python代码——使用动态IP

    目录 Virtual Private Network 代理服务器 测试代理IP是否生效 上一篇博文UN Comtrade(联合国商品贸易统计数据库)数据爬取Python代码讲了如何使用Python爬取 ...

  6. [Python]网站数据爬取任务

    Python爬虫作业:网站数据爬取任务 从以下网址(包括但不限于下列网络或应用)中爬取数据,以核实的形式存储数据,并进行分析(不一定是计算机角度的分析,可写分析报告),或制作词云图. 一.文本数据 酷 ...

  7. Python实践 - 网络爬虫笔记 - 2、从网站上爬取公开信息

    Python实践笔记 - 2.从网站上爬取公开信息 张板书的Python的实践笔记,包括笔记与DeBug的经历. 为了完成一个比较麻烦的实习任务,尝试着做了这样一个爬虫项目. 任务要求之一是要检索安徽 ...

  8. python简单网站爬虫-爬取北京7天最高、最低气温

    python简单网站爬虫-爬取北京7天最高.最低气温 前置操作: 1.待爬取网站: 北京天气的网址: http://www.weather.com.cn/weather1d/101010100.sht ...

  9. Python爬虫——简单爬取(从网站上爬取一本小说)

    从笔下文学网站爬取一本名为<剑来>的小说,作者为烽火戏诸侯 网站网址如下:https://www.bxwxorg.com/ ①通过查看网页源码找规律(在此之前请弄清楚网站允许爬取的部分,就 ...

最新文章

  1. 生物学的机器学习:使用K-Means和PCA进行基因组序列分析 COVID-19接下来如何突变?...
  2. 用navixt连接mysql连接不上_AMD神秘新显卡现身CompuBench数据库,可能是7nm Navi
  3. oracle linux 5.8安装oracle 11g rac环境之grid安装
  4. 用variance和bias解释其overfitting
  5. Redis进阶-Jedis以及Spring Boot操作 Redis 5.x Cluster
  6. 实现Repeater控件的记录单选(二)
  7. 用计算机弹传说之下鱼姐的bgm,传说之下战斗曲曲谱_传说之下打托丽尔的bgm
  8. Hadoop:Hadoop基本命令
  9. ASP.NET MVC传送参数至服务端
  10. 在线演示(动画演示)各种算法的实现过程
  11. appium : 查看Android手机自带浏览器内核版本(webview版本)
  12. Tinkpad笔记本双击开发Q盘不再提示创建恢复介质的对话框了,而且进入磁盘后文件夹是空的!
  13. WPF遍历视觉树与逻辑树
  14. 怀旧服一区和五区服务器位置,魔兽怀旧服战场分组怎么看?怀旧服战场分组一区五区怎么分的?...
  15. 特征工程 特征选择 reliefF算法
  16. 三十二位计算机游戏推荐,这32种课间游戏不重样,总有一款适合您和学生!| 推荐收藏...
  17. 《转》【LTE基础知识】LTE之S1接口与X1接口介绍
  18. 他人炒股心得,值得借鉴
  19. 局域网访问IIS express
  20. java面试题系列(一)

热门文章

  1. c语言 枚举定义变量,C语言之枚举的定义以及测试
  2. 基于matlab的脑瘤mr图像处理_基于Matlab GUI的医学图像处理课程虚拟实验平台设计...
  3. python什么时候用类_python中什么时候使用自定义类
  4. 万物根源-一分钟教你发布npm包
  5. 成功打开华三模拟器后,创建设备完成却启动设备失败
  6. wordpress中PHP运行错最有效解决办法Fatal error: Out of memory (allocated 6029312)(转)
  7. Sublime Text 3插件收集
  8. 使用Trello看板管理项目
  9. Hamilton Verissimo的blog
  10. 中缀表达式转换成后缀表达式