鱼C论坛

 找回密码
 立即注册
查看: 21667|回复: 34

[已解决]爬虫

[复制链接]
发表于 2023-3-5 13:14:36 | 显示全部楼层 |阅读模式

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

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

x
请问这个时间怎么为空啊
  1. import requests
  2. import re
  3. from time import sleep
  4. from lxml import html
  5. etree = html.etree


  6. header = {
  7.    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"
  8. }

  9. url = 'http://guba.eastmoney.com/news,cjpl,918454004.html'
  10. rsponse= requests.get(url=url,headers=header).text
  11. tree = etree.HTML(rsponse)
  12. data = tree.xpath('//*[@id="line2"]/div[1]/span[2]/text()')
  13. print(data)
复制代码
最佳答案
2023-3-5 14:05:25
那个是 js 动态渲染出来的,因为 requests 不会帮你自动获取静态资源(js、css)来渲染,

他只会帮你请求那个页面的 html 源代码,所以没有时间那个元素,教你一个判断是不是 js 渲染出来的方法,

禁用 js 然后刷新页面,看不到的那些元素都是 js 渲染出来的,禁用 js 的方法:

截图20230305135852.png

截图20230305135910.png

这种情况没有什么太好的解决方法,只能借助浏览器来帮你渲染,可以用 selenium,pypeeteer,playwright 等自动化的库,

也可以用 request-html 这个库,这个库就是 requests 与 pypeeteer 的结合,它也是 requests 官方开发的,

还有一种方法就是自己获取 js 来执行并把它渲染到 html 上,这种方法更是难
屏幕截图(37).png
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2023-3-5 13:15:30 | 显示全部楼层
不叫他他也会来的
@isdkz
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-3-5 13:34:06 | 显示全部楼层
liuhongrun2022 发表于 2023-3-5 13:15
不叫他他也会来的
@isdkz

我有看到,不过我刚刚要吃饭去了,回去再看看
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2023-3-5 13:39:19 | 显示全部楼层
liuhongrun2022 发表于 2023-3-5 13:15
不叫他他也会来的
@isdkz

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2023-3-5 13:39:33 | 显示全部楼层
isdkz 发表于 2023-3-5 13:34
我有看到,不过我刚刚要吃饭去了,回去再看看

好的
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2023-3-5 13:43:49 | 显示全部楼层

我也是这个问题,不过我是find没找到,@isdkz 大神……
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-3-5 14:05:25 | 显示全部楼层    本楼为最佳答案   
那个是 js 动态渲染出来的,因为 requests 不会帮你自动获取静态资源(js、css)来渲染,

他只会帮你请求那个页面的 html 源代码,所以没有时间那个元素,教你一个判断是不是 js 渲染出来的方法,

禁用 js 然后刷新页面,看不到的那些元素都是 js 渲染出来的,禁用 js 的方法:

截图20230305135852.png

截图20230305135910.png

这种情况没有什么太好的解决方法,只能借助浏览器来帮你渲染,可以用 selenium,pypeeteer,playwright 等自动化的库,

也可以用 request-html 这个库,这个库就是 requests 与 pypeeteer 的结合,它也是 requests 官方开发的,

还有一种方法就是自己获取 js 来执行并把它渲染到 html 上,这种方法更是难
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-3-5 14:11:11 | 显示全部楼层
isdkz 发表于 2023-3-5 14:05
那个是 js 动态渲染出来的,因为 requests 不会帮你自动获取静态资源(js、css)来渲染,

他只会帮你请 ...

大佬,麻烦您帮我看一下这个代码。有几个报错的地方不会填
  1. # -*- coding: utf-8 -*-
  2. """
  3. Created on Tue Feb 15 15:02:26 2023

  4. @author: Neal
  5. shareholder information of a stock are listed in :
  6. https://q.stock.sohu.com/cn/000001/ltgd.shtml
  7. https://q.stock.sohu.com/cn/000002/ltgd.shtml
  8. https://q.stock.sohu.com/cn/000003/ltgd.shtml
  9. ...

  10.     1. 'rank'-股票代码
  11.     2. 'rank'-排名
  12.     3. 'org_name'-股东名称
  13.     4. 'shares'-持股数量(万股)
  14.     5. 'percentage'-持股比例
  15.     6. 'changes'-持股变化(万股)
  16.     7. 'nature'-股本性质
  17. """

  18. import requests
  19. from bs4 import BeautifulSoup
  20. import pandas as pd
  21. import time
  22. fake_header = {  "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36",
  23.             "Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
  24.             "Accept-Encoding":"gzip, deflate, sdch",
  25.             "Accept-Language":"zh-TW,zh;q=0.8,en-US;q=0.6,en;q=0.4,zh-CN;q=0.2"
  26.         }

  27. data_file= './data/stock_shareholders.csv'
  28. select_stocks = ('601186','601169','601166','601088','601006','600523',
  29.              '600999','601988','600919','600887','600837','600606','600547',
  30.              '600519','600518','600485','600340','601881','600104','600100')


  31. print('There are', len(select_stocks), 'stocks in select_stocks')

  32. base_url = 'https://q.stock.sohu.com/cn/{}/ltgd.shtml'
  33. row_count = 0

  34. results=[]
  35. for stock in select_stocks:
  36.     url = base_url.format(stock)
  37.     print("Now we are crawling stock",stock)
  38.    
  39.     response = requests.get(url,headers = fake_header)
  40.     if response.status_code == 200:
  41.         response.encoding =  'gbk'
  42.         root = BeautifulSoup(response.text,"html.parser")
  43.         # search the table storing the shareholder information
  44.         table = root.select('body > div.str2Column.clearfix > div.str2ColumnR > div.BIZ_innerMain > div.BIZ_innerBoard > div > div:nth-child(2) > table > tbody > tr:nth-child(2) > td:nth-child(2) > a')#++insert your code here++
  45.         print(table)
  46.         
  47.         rows =
  48.         for row in rows:
  49.             record=[stock,]
  50.             columns =  
  51.             for col in columns: #iterate colums
  52.                 record.append(col.get_text().strip())
  53.             if len(record) == 7:
  54.                 row_count+=1
  55.         time.sleep(1)
  56. print('Crawled and saved {} records of  shareholder information of select_stocks to{}'.format(row_count,data_file) )

  57. sharehold_records_df = pd.DataFrame(columns=['stock', 'rank','org_name','shares','percentage','changes','nature'], data=results)
  58. sharehold_records_df.to_excel("./data/sharehold_records.xlsx")

  59. print("List of shareholers are \n", sharehold_records_df['org_name'])

复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-3-5 14:14:33 | 显示全部楼层
isdkz 发表于 2023-3-5 14:05
那个是 js 动态渲染出来的,因为 requests 不会帮你自动获取静态资源(js、css)来渲染,

他只会帮你请 ...

52行的table是要股东信息,我写的还是返回还是空,55行和58行那个不知道该咋填,看不懂
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-3-5 14:25:40 | 显示全部楼层
哈岁NB 发表于 2023-3-5 14:14
52行的table是要股东信息,我写的还是返回还是空,55行和58行那个不知道该咋填,看不懂

这里有一个坑就是你直接在浏览器复制的路径带有 table 的时候一般会带个 tbody,这是浏览器在渲染的时候自动给你补上去的,

一般别人写代码的时候没有那么标准,也为了省事都不写这个 tbody 的,

所以你把这个 tbody 去掉一般都可以获取到元素,除非其中还有一些动态渲染的元素在,

至于第 55 行和第 58 行,我也没看懂这是要干嘛?你这个是填程序的题?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-3-5 14:28:40 | 显示全部楼层
isdkz 发表于 2023-3-5 14:25
这里有一个坑就是你直接在浏览器复制的路径带有 table 的时候一般会带个 tbody,这是浏览器在渲染的时候 ...


是了,这样看看,这个有英文注释
  1. # -*- coding: utf-8 -*-
  2. """
  3. Created on Tue Feb 15 15:02:26 2023

  4. @author: Neal
  5. shareholder information of a stock are listed in :
  6. https://q.stock.sohu.com/cn/000001/ltgd.shtml
  7. https://q.stock.sohu.com/cn/000002/ltgd.shtml
  8. https://q.stock.sohu.com/cn/000003/ltgd.shtml
  9. ...

  10. And you are requried to collect the tables of shareholder information for stocks in "select_stocks"
  11. with following 7 columns, and then perform the analysis to answer the questions.
  12.     1. 'rank'-股票代码
  13.     2. 'rank'-排名
  14.     3. 'org_name'-股东名称       
  15.     4. 'shares'-持股数量(万股)
  16.     5. 'percentage'-持股比例       
  17.     6. 'changes'-持股变化(万股)
  18.     7. 'nature'-股本性质
  19. """

  20. import requests
  21. from bs4 import BeautifulSoup
  22. import pandas as pd
  23. import time
  24. fake_header = {  "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36",
  25.             "Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
  26.             "Accept-Encoding":"gzip, deflate, sdch",
  27.             "Accept-Language":"zh-TW,zh;q=0.8,en-US;q=0.6,en;q=0.4,zh-CN;q=0.2"
  28.         }

  29. data_file= './data/stock_shareholders.csv'
  30. select_stocks = ('601186','601169','601166','601088','601006','600523',
  31.              '600999','601988','600919','600887','600837','600606','600547',
  32.              '600519','600518','600485','600340','601881','600104','600100')


  33. print('There are', len(select_stocks), 'stocks in select_stocks')

  34. base_url = 'https://q.stock.sohu.com/cn/{}/ltgd.shtml'
  35. row_count = 0
  36. #create a list to store the crawled share-holdoing records
  37. results=[]
  38. for stock in select_stocks:#process stock one by one
  39.     #prepare the request webpage with desired parameters
  40.     url = base_url.format(stock)
  41.     print("Now we are crawling stock",stock)
  42.     #send http request with fake http header
  43.     response = requests.get(url,headers = fake_header)
  44.     if response.status_code == 200:
  45.         response.encoding =  'gbk'#++insert your code here++  look for charset in html
  46.         root = BeautifulSoup(response.text,"html.parser")
  47.         # search the table storing the shareholder information
  48.         table = root.select('body > div.str2Column.clearfix > div.str2ColumnR > div.BIZ_innerMain > div.BIZ_innerBoard > div > div:nth-child(2) > table tr:nth-child(2) > td:nth-child(2) > a')#++insert your code here++
  49.         print(table)

  50.         # list all rows the table, i.e., tr tags
  51.         rows = #++insert your code here++
  52.         for row in rows: #iterate rows
  53.             record=[stock,]# define a record with stock pre-filled and then store columns of the row/record
  54.             # list all columns of the row , i.e., td tags
  55.             columns =  #++insert your code here++
  56.             for col in columns: #iterate colums
  57.                 record.append(col.get_text().strip())
  58.             if len(record) == 7:# if has valid columns, save the record to list results
  59.                 #++insert your code here++ to add single "record" to list of "records"
  60.                 row_count+=1
  61.         time.sleep(1)
  62. print('Crawled and saved {} records of  shareholder information of select_stocks to{}'.format(row_count,data_file) )

  63. sharehold_records_df = pd.DataFrame(columns=['stock', 'rank','org_name','shares','percentage','changes','nature'], data=results)
  64. sharehold_records_df.to_excel("./data/sharehold_records.xlsx")

  65. print("List of shareholers are \n", sharehold_records_df['org_name'])


  66. ++insert your code here++ to answer Q3-1, Q3-2 and Q3-3
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-3-5 14:37:52 | 显示全部楼层
本帖最后由 isdkz 于 2023-3-5 14:49 编辑
哈岁NB 发表于 2023-3-5 14:28
是了,这样看看,这个有英文注释


  1. # -*- coding: utf-8 -*-
  2. """
  3. Created on Tue Feb 15 15:02:26 2023

  4. @author: Neal
  5. shareholder information of a stock are listed in :
  6. https://q.stock.sohu.com/cn/000001/ltgd.shtml
  7. https://q.stock.sohu.com/cn/000002/ltgd.shtml
  8. https://q.stock.sohu.com/cn/000003/ltgd.shtml
  9. ...

  10. And you are requried to collect the tables of shareholder information for stocks in "select_stocks"
  11. with following 7 columns, and then perform the analysis to answer the questions.
  12.     1. 'rank'-股票代码
  13.     2. 'rank'-排名
  14.     3. 'org_name'-股东名称        
  15.     4. 'shares'-持股数量(万股)
  16.     5. 'percentage'-持股比例        
  17.     6. 'changes'-持股变化(万股)
  18.     7. 'nature'-股本性质
  19. """

  20. import requests
  21. from bs4 import BeautifulSoup
  22. import pandas as pd
  23. import time
  24. fake_header = {  "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36",
  25.             "Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
  26.             "Accept-Encoding":"gzip, deflate, sdch",
  27.             "Accept-Language":"zh-TW,zh;q=0.8,en-US;q=0.6,en;q=0.4,zh-CN;q=0.2"
  28.         }

  29. data_file= './data/stock_shareholders.csv'
  30. select_stocks = ('601186','601169','601166','601088','601006','600523',
  31.              '600999','601988','600919','600887','600837','600606','600547',
  32.              '600519','600518','600485','600340','601881','600104','600100')


  33. print('There are', len(select_stocks), 'stocks in select_stocks')

  34. base_url = 'https://q.stock.sohu.com/cn/{}/ltgd.shtml'
  35. row_count = 0
  36. #create a list to store the crawled share-holdoing records
  37. results=[]
  38. for stock in select_stocks:#process stock one by one
  39.     #prepare the request webpage with desired parameters
  40.     url = base_url.format(stock)
  41.     print("Now we are crawling stock",stock)
  42.     #send http request with fake http header
  43.     response = requests.get(url,headers = fake_header)
  44.     if response.status_code == 200:
  45.         response.encoding =  'gbk'#++insert your code here++  look for charset in html
  46.         root = BeautifulSoup(response.text,"html.parser")
  47.         # search the table storing the shareholder information
  48.         table = root.select_one('body > div.str2Column.clearfix > div.str2ColumnR > div.BIZ_innerMain > div.BIZ_innerBoard > div > div:nth-child(2) > table')#++insert your code here++
  49.         print(table)

  50.         # list all rows the table, i.e., tr tags
  51.         rows = table.select('tr')#++insert your code here++
  52.         for row in rows: #iterate rows
  53.             record=[stock,]# define a record with stock pre-filled and then store columns of the row/record
  54.             # list all columns of the row , i.e., td tags
  55.             columns = row.select('td') #++insert your code here++
  56.             for col in columns: #iterate colums
  57.                 record.append(col.get_text().strip())
  58.             if len(record) == 7:# if has valid columns, save the record to list results
  59.                 #++insert your code here++ to add single "record" to list of "records"
  60.                 results.append(record)
  61.                 row_count+=1
  62.         time.sleep(1)
  63. print('Crawled and saved {} records of  shareholder information of select_stocks to{}'.format(row_count,data_file) )


  64. #######################   如果你的代码中没有 data 这个文件夹,加上这段代码以免报错
  65. import os
  66. if not os.path.exists('data'):
  67.     os.mkdir('data')
  68. #######################


  69. sharehold_records_df = pd.DataFrame(columns=['stock', 'rank','org_name','shares','percentage','changes','nature'], data=results)
  70. sharehold_records_df.to_excel("./data/sharehold_records.xlsx")

  71. print("List of shareholers are \n", sharehold_records_df['org_name'])


  72. #++insert your code here++ to answer Q3-1, Q3-2 and Q3-3
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-3-5 14:48:02 | 显示全部楼层

这是怎么回事呢
屏幕截图(39).png
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-3-5 14:51:49 | 显示全部楼层
哈岁NB 发表于 2023-3-5 14:48
这是怎么回事呢

因为你当前工作目录中没有 data 这个文件夹,

sharehold_records_df.to_excel("./data/sharehold_records.xlsx") 而这一句代码是保存到 data 这个文件夹中,

我在回复中的代码也加了相应的代码:

截图20230305145005.png
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-3-5 14:53:03 | 显示全部楼层

解决了,解决了,代码放错地方了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-3-5 15:10:16 | 显示全部楼层
isdkz 发表于 2023-3-5 14:51
因为你当前工作目录中没有 data 这个文件夹,

sharehold_records_df.to_excel("./data/sharehold_reco ...

bs4是不是只能这么一个一个往下套,不能像xpath一步到位啊
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-3-5 15:20:42 | 显示全部楼层
哈岁NB 发表于 2023-3-5 15:10
bs4是不是只能这么一个一个往下套,不能像xpath一步到位啊

不是呀,也可以直接定位到特定的元素呀
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-3-5 15:26:30 | 显示全部楼层
isdkz 发表于 2023-3-5 15:20
不是呀,也可以直接定位到特定的元素呀

那这个该怎么写才能直接把股东信息提取出来呢
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-3-5 15:27:47 | 显示全部楼层
哈岁NB 发表于 2023-3-5 15:26
那这个该怎么写才能直接把股东信息提取出来呢

.select('body > div.str2Column.clearfix > div.str2ColumnR > div.BIZ_innerMain > div.BIZ_innerBoard > div > div:nth-child(2) > table > tr:nth-child(2) > td:nth-child(2) > a')
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-3-5 15:33:00 | 显示全部楼层
isdkz 发表于 2023-3-5 15:27
.select('body > div.str2Column.clearfix > div.str2ColumnR > div.BIZ_innerMain > div.BIZ_innerBoard ...

这个不是把标签所有的内容输出了吗,如果单独想要这个标签的文本呢
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-4-24 21:58

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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