Popular New Releases in Selenium
scrapy
1.8.2
playwright
v1.21.1
selenium
Selenium 4.1.0
rrweb
rrweb@1.1.3; rrweb-player@0.7.14; rrweb-snapshot@1.1.14
nightwatch
v2.1.0
Popular Libraries in Selenium
by scrapy python
42899 NOASSERTION
Scrapy, a fast high-level web crawling & scraping framework for Python.
by microsoft typescript
36789 Apache-2.0
Playwright is a framework for Web Testing and Automation. It allows testing Chromium, Firefox and WebKit with a single API.
by SeleniumHQ java
23180 Apache-2.0
A browser automation framework and ecosystem.
by Kr1s77 python
13481 NOASSERTION
😮python模拟登陆一些大型网站,还有一些简单的爬虫,希望对你们有所帮助❤️,如果喜欢记得给个star哦🌟
by prisma-archive typescript
13250 MIT
🖥 Chrome automation made simple. Runs locally or headless on AWS Lambda.
by timgrossmann python
13182 GPL-3.0
📷 Instagram Bot - Tool for automated Instagram interactions
by rrweb-io typescript
11468 MIT
record and replay the web
by nightwatchjs javascript
11057 MIT
End-to-end testing framework written in Node.js and using the W3C Webdriver API
by hyb1996 java
10414 MPL-2.0
A UiAutomator on android, does not need root access(安卓平台上的JavaScript自动化工具)
Trending New libraries in Selenium
by alirezamika python
3565 MIT
A Smart, Automatic, Fast and Lightweight Web Scraper for Python
by microsoft javascript
1421 MIT
.NET version of the Playwright testing and automation library.
by gh0stkey html
917
Web Fuzzing Box - Web 模糊测试字典与一些Payloads,主要包含:弱口令暴力破解、目录以及文件枚举、Web漏洞...字典运用于实战案例:https://gh0st.cn/archives/2019-11-11/1
by microsoft csharp
684 MIT
.NET version of the Playwright testing and automation library.
by QIN2DIM python
553 MIT
采集免费、优质的机场订阅链接;科学上网,从娃娃抓起!
by g1879 python
539 BSD-3-Clause
A module that integrates selenium and requests session, encapsulates common page operations, can achieve seamless switching between the two modes.
by mxschmitt javascript
531 MIT
Playwright for Go a browser automation library to control Chromium, Firefox and WebKit with a single API.
by alexal1 python
505 MIT
Instagram bot for automated Instagram interaction using Android device via ADB
by IBMa javascript
489 Apache-2.0
IBM Equal Access Accessibility Checker contains tools to automate accessibility checking from a browser or in a continuous development/build environment
Top Authors in Selenium
1
43 Libraries
247
2
37 Libraries
657
3
32 Libraries
95
4
31 Libraries
471
5
17 Libraries
58
6
17 Libraries
553
7
13 Libraries
2463
8
12 Libraries
1803
9
12 Libraries
48
10
10 Libraries
78
1
43 Libraries
247
2
37 Libraries
657
3
32 Libraries
95
4
31 Libraries
471
5
17 Libraries
58
6
17 Libraries
553
7
13 Libraries
2463
8
12 Libraries
1803
9
12 Libraries
48
10
10 Libraries
78
Trending Kits in Selenium
No Trending Kits are available at this moment for Selenium
Trending Discussions on Selenium
Selenium-chromedriver: Cannot construct KeyEvent from non-typeable key
Python Selenium AWS Lambda Change WebGL Vendor/Renderer For Undetectable Headless Scraper
How To Set ChromeOptions (or goog:ChromeOptions) for Selenium::Chrome in Perl
DeprecationWarning: executable_path has been deprecated, please pass in a Service object
How can I send Dynamic website content to scrapy with the html content generated by selenium browser?
Python/Selenium web scrap how to find hidden src value from a links?
Efficient code for custom color formatting in tkinter python
Unable to build and deploy Rails 6.0.4.1 app on heroku - Throws gyp verb cli error
Log4j 1: How to mitigate the vulnerability in log4j without updating version to 2.15.0
TypeError: WebDriver.__init__() got an unexpected keyword argument 'firefox_options' error using firefox_options as arguments in Selenium Python
QUESTION
Selenium-chromedriver: Cannot construct KeyEvent from non-typeable key
Asked 2022-Mar-25 at 12:17I updated my Chrome and Chromedriver to the latest version yesterday, and since then I get the following error messages when running my Cucumber features:
1....
2unknown error: Cannot construct KeyEvent from non-typeable key
3 (Session info: chrome=98.0.4758.80) (Selenium::WebDriver::Error::UnknownError)
4 #0 0x55e9ce6a4093 <unknown>
5 #1 0x55e9ce16a648 <unknown>
6 #2 0x55e9ce1a9866 <unknown>
7 #3 0x55e9ce1cbd29 <unknown>
8 .....
9
I try to fill a text field with Capybara's fill_in
method. While debugging I noticed that Capybara has problems especially with the symbols @
and \
. Every other character can be written into the text field without any problems.
The code that triggers the error looks like this
1....
2unknown error: Cannot construct KeyEvent from non-typeable key
3 (Session info: chrome=98.0.4758.80) (Selenium::WebDriver::Error::UnknownError)
4 #0 0x55e9ce6a4093 <unknown>
5 #1 0x55e9ce16a648 <unknown>
6 #2 0x55e9ce1a9866 <unknown>
7 #3 0x55e9ce1cbd29 <unknown>
8 .....
9def sign_in(user)
10 visit new_sign_in_path
11 fill_in 'Email', with: user.email
12 fill_in 'Password', with: user.password
13 click_button 'Sign in'
14end
15
user.email
contains a string like "example1@mail.com"
.
I work with Rails 6.1.3.1, Cucumber 5.3.0, Chromedriver 98.0.4758.48, capybara 3.35.3
The error only occurs on features that are tagged with @javascript
Do you have any ideas what causes this error or how to fix it?
ANSWER
Answered 2022-Feb-03 at 08:25It seems something has changed in the new version of ChromeDriver and it is no longer possible to send some special chars directly using send_keys method.
In this link you will see how it is solved (in C#) --> Selenium - SendKeys("@") write an "à"
And regarding python implementation, check this out --> https://www.geeksforgeeks.org/special-keys-in-selenium-python/
Specifically, my implementation was (using MAC):
1....
2unknown error: Cannot construct KeyEvent from non-typeable key
3 (Session info: chrome=98.0.4758.80) (Selenium::WebDriver::Error::UnknownError)
4 #0 0x55e9ce6a4093 <unknown>
5 #1 0x55e9ce16a648 <unknown>
6 #2 0x55e9ce1a9866 <unknown>
7 #3 0x55e9ce1cbd29 <unknown>
8 .....
9def sign_in(user)
10 visit new_sign_in_path
11 fill_in 'Email', with: user.email
12 fill_in 'Password', with: user.password
13 click_button 'Sign in'
14end
15driver.find_element('.email-input', 'user@mail.com')
16
Now I had to change it by:
1....
2unknown error: Cannot construct KeyEvent from non-typeable key
3 (Session info: chrome=98.0.4758.80) (Selenium::WebDriver::Error::UnknownError)
4 #0 0x55e9ce6a4093 <unknown>
5 #1 0x55e9ce16a648 <unknown>
6 #2 0x55e9ce1a9866 <unknown>
7 #3 0x55e9ce1cbd29 <unknown>
8 .....
9def sign_in(user)
10 visit new_sign_in_path
11 fill_in 'Email', with: user.email
12 fill_in 'Password', with: user.password
13 click_button 'Sign in'
14end
15driver.find_element('.email-input', 'user@mail.com')
16from selenium.webdriver.common.keys import Keys
17from selenium.webdriver.common.action_chains import ActionChains
18
19emailParts = 'user@mail.com'.split('@')
20emailElement = driver.find_element('.email-input')
21
22emailElement.send_keys(emailParts[0])
23action = ActionChains(driver)
24action.key_down(Keys.ALT).send_keys('2').key_up(Keys.ALT).perform()
25emailElement.send_keys(emailParts[1])
26
QUESTION
Python Selenium AWS Lambda Change WebGL Vendor/Renderer For Undetectable Headless Scraper
Asked 2022-Mar-21 at 20:19Using AWS Lambda functions with Python and Selenium, I want to create a undetectable headless chrome scraper by passing a headless chrome test. I check the undetectability of my headless scraper by opening up the test and taking a screenshot. I ran this test on a Local IDE and on a Lambda server.
Implementation:
I will be using a python library called selenium-stealth and will follow their basic configuration:
1stealth(driver,
2 languages=["en-US", "en"],
3 vendor="Google Inc.",
4 platform="Win32",
5 webgl_vendor="Intel Inc.",
6 renderer="Intel Iris OpenGL Engine",
7 fix_hairline=True,
8 )
9
I implemented this configuration on a Local IDE as well as an AWS Lambda Server to compare the results.
Local IDE:
Found below are the test results running on a local IDE:
Lambda Server:
When I run this on a Lambda server, both the WebGL Vendor and Renderer are blank. as shown below:
I even tried to manually change the WebGL Vendor/Renderer using the following JavaScript command:
1stealth(driver,
2 languages=["en-US", "en"],
3 vendor="Google Inc.",
4 platform="Win32",
5 webgl_vendor="Intel Inc.",
6 renderer="Intel Iris OpenGL Engine",
7 fix_hairline=True,
8 )
9driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {"source": "WebGLRenderingContext.prototype.getParameter = function(parameter) {if (parameter === 37445) {return 'VENDOR_INPUT';}if (parameter === 37446) {return 'RENDERER_INPUT';}return getParameter(parameter);};"})
10
Then I thought maybe that it could be something wrong with the parameter number. I configured the command execution without the if statement, but the same thing happened: It worked on my Local IDE but had no effect on an AWS Lambda Server.
Simply Put:Is it possible to add Vendor/Renderer on AWS Lambda? In my efforts, it seems that there is no possible way. I made sure to submit this issue on the selenium-stealth GitHub Repository.
ANSWER
Answered 2021-Dec-18 at 02:01WebGL is a cross-platform, open web standard for a low-level 3D graphics API based on OpenGL ES, exposed to ECMAScript via the HTML5 Canvas element. WebGL at it's core is a Shader-based API using GLSL, with constructs that are semantically similar to those of the underlying OpenGL ES API. It follows the OpenGL ES specification, with some exceptions for the out of memory-managed languages such as JavaScript. WebGL 1.0 exposes the OpenGL ES 2.0 feature set; WebGL 2.0 exposes the OpenGL ES 3.0 API.
Now, with the availability of Selenium Stealth building of Undetectable Scraper using Selenium driven ChromeDriver initiated google-chrome Browsing Context have become much more easier.
selenium-stealth
selenium-stealth is a python package selenium-stealth to prevent detection. This programme tries to make python selenium more stealthy. However, as of now selenium-stealth only support Selenium Chrome.
Code Block:
1stealth(driver,
2 languages=["en-US", "en"],
3 vendor="Google Inc.",
4 platform="Win32",
5 webgl_vendor="Intel Inc.",
6 renderer="Intel Iris OpenGL Engine",
7 fix_hairline=True,
8 )
9driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {"source": "WebGLRenderingContext.prototype.getParameter = function(parameter) {if (parameter === 37445) {return 'VENDOR_INPUT';}if (parameter === 37446) {return 'RENDERER_INPUT';}return getParameter(parameter);};"})
10from selenium import webdriver
11from selenium.webdriver.chrome.options import Options
12from selenium.webdriver.chrome.service import Service
13from selenium_stealth import stealth
14
15options = Options()
16options.add_argument("start-maximized")
17options.add_experimental_option("excludeSwitches", ["enable-automation"])
18options.add_experimental_option('useAutomationExtension', False)
19s = Service('C:\\BrowserDrivers\\chromedriver.exe')
20driver = webdriver.Chrome(service=s, options=options)
21
22# Selenium Stealth settings
23stealth(driver,
24 languages=["en-US", "en"],
25 vendor="Google Inc.",
26 platform="Win32",
27 webgl_vendor="Intel Inc.",
28 renderer="Intel Iris OpenGL Engine",
29 fix_hairline=True,
30 )
31
32driver.get("https://bot.sannysoft.com/")
33
Browser Screenshot:
You can find a detailed relevant discussion in Can a website detect when you are using Selenium with chromedriver?
Changing WebGL Vendor/Renderer in AWS Lambda
AWS Lambda enables us to deliver compressed WebGL websites to end users. When requested webpage objects are compressed, the transfer size is reduced, leading to faster downloads, lower cloud storage fees, and lower data transfer fees. Improved load times also directly influence the viewer experience and retention, which helps in improving website conversion and discoverability. Using WebGL, websites are more immersive while still being accessible via a browser URL. Through this technique AWS Lambda to automatically compress the objects uploaded to S3.
Background on compression and WebGLHTTP compression is a capability that can be built into web servers and web clients to improve transfer speed and bandwidth utilization. This capability is negotiated between the server and the client using an HTTP header which may indicate that a resource being transferred, cached, or otherwise referenced is compressed. AWS Lambda on the server-side supports Content-Encoding header.
On the client-side, most browsers today support brotli and gzip compression through HTTP headers (Accept-Encoding: deflate, br, gzip
) and can handle server response headers. This means browsers will automatically download and decompress content from a web server at the client-side, before rendering webpages to the viewer.
Conclusion
Due to this constraint you may not be able to change the WebGL Vendor/Renderer in AWS Lambda, else it may directly affect the process of rendering webpages to the viewers and can stand out to be a bottleneck in UX.
tl; dr
You can find a couple of relevant detailed discussion in:
QUESTION
How To Set ChromeOptions (or goog:ChromeOptions) for Selenium::Chrome in Perl
Asked 2022-Mar-18 at 09:33In Python, I could easily change the browser "navigator.webdriver" property to false, when using the local chromedriver with my local Chrome browser.
1from selenium import webdriver
2
3options = webdriver.ChromeOptions()
4options.add_argument("--disable-blink-features=AutomationControlled")
5driver = webdriver.Chrome(chrome_options=options)
6driver.get([some url])
7
After the above, in the Chrome browser console, navigator.webdriver would show "false".
But I do not know how to translate the above to Perl. The following code would still leave the navigator.webdriver as "true". So how do I implement the Python code above in Perl? Is it possible (ideally without using the remote stand-alone selenium server)?
1from selenium import webdriver
2
3options = webdriver.ChromeOptions()
4options.add_argument("--disable-blink-features=AutomationControlled")
5driver = webdriver.Chrome(chrome_options=options)
6driver.get([some url])
7use strict;
8use warnings;
9use Selenium::Chrome;
10my $driver = Selenium::Chrome->new(
11 custom_args => '--disable-blink-features=AutomationControlled' );
12$driver->get([some url]);
13
Any help would be greatly appreciated!
ANSWER
Answered 2022-Mar-18 at 09:33Need to use extra_capabilities
with goog:chromeOptions
1from selenium import webdriver
2
3options = webdriver.ChromeOptions()
4options.add_argument("--disable-blink-features=AutomationControlled")
5driver = webdriver.Chrome(chrome_options=options)
6driver.get([some url])
7use strict;
8use warnings;
9use Selenium::Chrome;
10my $driver = Selenium::Chrome->new(
11 custom_args => '--disable-blink-features=AutomationControlled' );
12$driver->get([some url]);
13my $drv = Selenium::Chrome->new(
14 'extra_capabilities' => {
15 'goog:chromeOptions' => {
16 prefs => { ... },
17 args => [
18 'window-position=960,10', 'window-size=950,1180', # etc
19 'disable-blink-features=AutomationControlled'
20 ]
21 }
22 }
23);
24
(I don't know how disable-blink-features
relates to that "navigator.webdriver")
For the list of attributes available in the constructor, along with the extra_capabilities
, see Selenium::Remote::Driver, from which Selenium::Chrome inherits.
For Chrome-specific capabilities see "Recognized capabilities" in chromedriver, and more generally see Selenium documentation and W3C WebDriver standard. †
† Specifically
WebDriver Capabilities in Selenium docs, and
Capabilities and extension ("extra") capabilities in WebDriver standard
QUESTION
DeprecationWarning: executable_path has been deprecated, please pass in a Service object
Asked 2022-Feb-14 at 12:45I started a selenium tutorial today and have run into this error when trying to run the code. I've tried other methods but ultimately get the same error. I'm on MacOS using VSC.
My Code:
1from selenium import webdriver
2
3PATH = '/Users/blutch/Documents/Chrom Web Driver\chromedriver.exe'
4driver = webdriver.Chrome(PATH)
5driver.get("https://www.google.com")
6
7
I've also tried inserting C: in front of /Users. Can anyone guide me on why this is happening/how to fix it?
ANSWER
Answered 2021-Nov-10 at 19:03This error message...
1from selenium import webdriver
2
3PATH = '/Users/blutch/Documents/Chrom Web Driver\chromedriver.exe'
4driver = webdriver.Chrome(PATH)
5driver.get("https://www.google.com")
6
7DeprecationWarning: executable_path has been deprecated, please pass in a Service object
8
...implies that the key executable_path
will be deprecated in the upcoming releases.
This change is inline with the Selenium 4.0 Beta 1 changelog which mentions:
Deprecate all but
Options
andService
arguments in driver instantiation. (#9125,#9128)
Solution
Once the key executable_path
is deprecated you have to use an instance of the Service()
class as follows:
1from selenium import webdriver
2
3PATH = '/Users/blutch/Documents/Chrom Web Driver\chromedriver.exe'
4driver = webdriver.Chrome(PATH)
5driver.get("https://www.google.com")
6
7DeprecationWarning: executable_path has been deprecated, please pass in a Service object
8from selenium import webdriver
9from selenium.webdriver.chrome.service import Service
10
11s = Service('C:/Users/.../chromedriver.exe')
12driver = webdriver.Chrome(service=s)
13
TL; DR
You can find a couple of relevant detailed discussion in:
QUESTION
How can I send Dynamic website content to scrapy with the html content generated by selenium browser?
Asked 2022-Jan-20 at 15:35I am working on certain stock-related projects where I have had a task to scrape all data on a daily basis for the last 5 years. i.e from 2016 to date. I particularly thought of using selenium because I can use crawler and bot to scrape the data based on the date. So I used the use of button click with selenium and now I want the same data that is displayed by the selenium browser to be fed by scrappy. This is the website I am working on right now. I have written the following code inside scrappy spider.
1class FloorSheetSpider(scrapy.Spider):
2 name = "nepse"
3
4 def start_requests(self):
5
6 driver = webdriver.Firefox(executable_path=GeckoDriverManager().install())
7
8
9 floorsheet_dates = ['01/03/2016','01/04/2016', up to till date '01/10/2022']
10
11 for date in floorsheet_dates:
12 driver.get(
13 "https://merolagani.com/Floorsheet.aspx")
14
15 driver.find_element(By.XPATH, "//input[@name='ctl00$ContentPlaceHolder1$txtFloorsheetDateFilter']"
16 ).send_keys(date)
17 driver.find_element(By.XPATH, "(//a[@title='Search'])[3]").click()
18 total_length = driver.find_element(By.XPATH,
19 "//span[@id='ctl00_ContentPlaceHolder1_PagerControl2_litRecords']").text
20 z = int((total_length.split()[-1]).replace(']', ''))
21 for data in range(z, z + 1):
22 driver.find_element(By.XPATH, "(//a[@title='Page {}'])[2]".format(data)).click()
23 self.url = driver.page_source
24 yield Request(url=self.url, callback=self.parse)
25
26
27 def parse(self, response, **kwargs):
28 for value in response.xpath('//tbody/tr'):
29 print(value.css('td::text').extract()[1])
30 print("ok"*200)
31
Update: Error after answer is
1class FloorSheetSpider(scrapy.Spider):
2 name = "nepse"
3
4 def start_requests(self):
5
6 driver = webdriver.Firefox(executable_path=GeckoDriverManager().install())
7
8
9 floorsheet_dates = ['01/03/2016','01/04/2016', up to till date '01/10/2022']
10
11 for date in floorsheet_dates:
12 driver.get(
13 "https://merolagani.com/Floorsheet.aspx")
14
15 driver.find_element(By.XPATH, "//input[@name='ctl00$ContentPlaceHolder1$txtFloorsheetDateFilter']"
16 ).send_keys(date)
17 driver.find_element(By.XPATH, "(//a[@title='Search'])[3]").click()
18 total_length = driver.find_element(By.XPATH,
19 "//span[@id='ctl00_ContentPlaceHolder1_PagerControl2_litRecords']").text
20 z = int((total_length.split()[-1]).replace(']', ''))
21 for data in range(z, z + 1):
22 driver.find_element(By.XPATH, "(//a[@title='Page {}'])[2]".format(data)).click()
23 self.url = driver.page_source
24 yield Request(url=self.url, callback=self.parse)
25
26
27 def parse(self, response, **kwargs):
28 for value in response.xpath('//tbody/tr'):
29 print(value.css('td::text').extract()[1])
30 print("ok"*200)
312022-01-14 14:11:36 [twisted] CRITICAL:
32Traceback (most recent call last):
33 File "/home/navaraj/PycharmProjects/first_scrapy/env/lib/python3.8/site-packages/twisted/internet/defer.py", line 1661, in _inlineCallbacks
34 result = current_context.run(gen.send, result)
35 File "/home/navaraj/PycharmProjects/first_scrapy/env/lib/python3.8/site-packages/scrapy/crawler.py", line 88, in crawl
36 start_requests = iter(self.spider.start_requests())
37TypeError: 'NoneType' object is not iterable
38
I want to send current web html content to scrapy feeder but I am getting unusal error for past 2 days any help or suggestions will be very much appreciated.
ANSWER
Answered 2022-Jan-14 at 09:30The 2 solutions are not very different. Solution #2 fits better to your question, but choose whatever you prefer.
Solution 1 - create a response with the html's body from the driver and scraping it right away (you can also pass it as an argument to a function):
1class FloorSheetSpider(scrapy.Spider):
2 name = "nepse"
3
4 def start_requests(self):
5
6 driver = webdriver.Firefox(executable_path=GeckoDriverManager().install())
7
8
9 floorsheet_dates = ['01/03/2016','01/04/2016', up to till date '01/10/2022']
10
11 for date in floorsheet_dates:
12 driver.get(
13 "https://merolagani.com/Floorsheet.aspx")
14
15 driver.find_element(By.XPATH, "//input[@name='ctl00$ContentPlaceHolder1$txtFloorsheetDateFilter']"
16 ).send_keys(date)
17 driver.find_element(By.XPATH, "(//a[@title='Search'])[3]").click()
18 total_length = driver.find_element(By.XPATH,
19 "//span[@id='ctl00_ContentPlaceHolder1_PagerControl2_litRecords']").text
20 z = int((total_length.split()[-1]).replace(']', ''))
21 for data in range(z, z + 1):
22 driver.find_element(By.XPATH, "(//a[@title='Page {}'])[2]".format(data)).click()
23 self.url = driver.page_source
24 yield Request(url=self.url, callback=self.parse)
25
26
27 def parse(self, response, **kwargs):
28 for value in response.xpath('//tbody/tr'):
29 print(value.css('td::text').extract()[1])
30 print("ok"*200)
312022-01-14 14:11:36 [twisted] CRITICAL:
32Traceback (most recent call last):
33 File "/home/navaraj/PycharmProjects/first_scrapy/env/lib/python3.8/site-packages/twisted/internet/defer.py", line 1661, in _inlineCallbacks
34 result = current_context.run(gen.send, result)
35 File "/home/navaraj/PycharmProjects/first_scrapy/env/lib/python3.8/site-packages/scrapy/crawler.py", line 88, in crawl
36 start_requests = iter(self.spider.start_requests())
37TypeError: 'NoneType' object is not iterable
38import scrapy
39from selenium import webdriver
40from selenium.webdriver.common.by import By
41from scrapy.http import HtmlResponse
42
43
44class FloorSheetSpider(scrapy.Spider):
45 name = "nepse"
46
47 def start_requests(self):
48
49 # driver = webdriver.Firefox(executable_path=GeckoDriverManager().install())
50 driver = webdriver.Chrome()
51
52 floorsheet_dates = ['01/03/2016','01/04/2016']#, up to till date '01/10/2022']
53
54 for date in floorsheet_dates:
55 driver.get(
56 "https://merolagani.com/Floorsheet.aspx")
57
58 driver.find_element(By.XPATH, "//input[@name='ctl00$ContentPlaceHolder1$txtFloorsheetDateFilter']"
59 ).send_keys(date)
60 driver.find_element(By.XPATH, "(//a[@title='Search'])[3]").click()
61 total_length = driver.find_element(By.XPATH,
62 "//span[@id='ctl00_ContentPlaceHolder1_PagerControl2_litRecords']").text
63 z = int((total_length.split()[-1]).replace(']', ''))
64 for data in range(1, z + 1):
65 driver.find_element(By.XPATH, "(//a[@title='Page {}'])[2]".format(data)).click()
66 self.body = driver.page_source
67
68 response = HtmlResponse(url=driver.current_url, body=self.body, encoding='utf-8')
69 for value in response.xpath('//tbody/tr'):
70 print(value.css('td::text').extract()[1])
71 print("ok"*200)
72
73 # return an empty requests list
74 return []
75
Solution 2 - with super simple downloader middleware:
(You might have a delay here in parse
method so be patient).
1class FloorSheetSpider(scrapy.Spider):
2 name = "nepse"
3
4 def start_requests(self):
5
6 driver = webdriver.Firefox(executable_path=GeckoDriverManager().install())
7
8
9 floorsheet_dates = ['01/03/2016','01/04/2016', up to till date '01/10/2022']
10
11 for date in floorsheet_dates:
12 driver.get(
13 "https://merolagani.com/Floorsheet.aspx")
14
15 driver.find_element(By.XPATH, "//input[@name='ctl00$ContentPlaceHolder1$txtFloorsheetDateFilter']"
16 ).send_keys(date)
17 driver.find_element(By.XPATH, "(//a[@title='Search'])[3]").click()
18 total_length = driver.find_element(By.XPATH,
19 "//span[@id='ctl00_ContentPlaceHolder1_PagerControl2_litRecords']").text
20 z = int((total_length.split()[-1]).replace(']', ''))
21 for data in range(z, z + 1):
22 driver.find_element(By.XPATH, "(//a[@title='Page {}'])[2]".format(data)).click()
23 self.url = driver.page_source
24 yield Request(url=self.url, callback=self.parse)
25
26
27 def parse(self, response, **kwargs):
28 for value in response.xpath('//tbody/tr'):
29 print(value.css('td::text').extract()[1])
30 print("ok"*200)
312022-01-14 14:11:36 [twisted] CRITICAL:
32Traceback (most recent call last):
33 File "/home/navaraj/PycharmProjects/first_scrapy/env/lib/python3.8/site-packages/twisted/internet/defer.py", line 1661, in _inlineCallbacks
34 result = current_context.run(gen.send, result)
35 File "/home/navaraj/PycharmProjects/first_scrapy/env/lib/python3.8/site-packages/scrapy/crawler.py", line 88, in crawl
36 start_requests = iter(self.spider.start_requests())
37TypeError: 'NoneType' object is not iterable
38import scrapy
39from selenium import webdriver
40from selenium.webdriver.common.by import By
41from scrapy.http import HtmlResponse
42
43
44class FloorSheetSpider(scrapy.Spider):
45 name = "nepse"
46
47 def start_requests(self):
48
49 # driver = webdriver.Firefox(executable_path=GeckoDriverManager().install())
50 driver = webdriver.Chrome()
51
52 floorsheet_dates = ['01/03/2016','01/04/2016']#, up to till date '01/10/2022']
53
54 for date in floorsheet_dates:
55 driver.get(
56 "https://merolagani.com/Floorsheet.aspx")
57
58 driver.find_element(By.XPATH, "//input[@name='ctl00$ContentPlaceHolder1$txtFloorsheetDateFilter']"
59 ).send_keys(date)
60 driver.find_element(By.XPATH, "(//a[@title='Search'])[3]").click()
61 total_length = driver.find_element(By.XPATH,
62 "//span[@id='ctl00_ContentPlaceHolder1_PagerControl2_litRecords']").text
63 z = int((total_length.split()[-1]).replace(']', ''))
64 for data in range(1, z + 1):
65 driver.find_element(By.XPATH, "(//a[@title='Page {}'])[2]".format(data)).click()
66 self.body = driver.page_source
67
68 response = HtmlResponse(url=driver.current_url, body=self.body, encoding='utf-8')
69 for value in response.xpath('//tbody/tr'):
70 print(value.css('td::text').extract()[1])
71 print("ok"*200)
72
73 # return an empty requests list
74 return []
75import scrapy
76from scrapy import Request
77from scrapy.http import HtmlResponse
78from selenium import webdriver
79from selenium.webdriver.common.by import By
80
81
82class SeleniumMiddleware(object):
83 def process_request(self, request, spider):
84 url = spider.driver.current_url
85 body = spider.driver.page_source
86 return HtmlResponse(url=url, body=body, encoding='utf-8', request=request)
87
88
89class FloorSheetSpider(scrapy.Spider):
90 name = "nepse"
91
92 custom_settings = {
93 'DOWNLOADER_MIDDLEWARES': {
94 'tempbuffer.spiders.yetanotherspider.SeleniumMiddleware': 543,
95 # 'projects_name.path.to.your.pipeline': 543
96 }
97 }
98 driver = webdriver.Chrome()
99
100 def start_requests(self):
101
102 # driver = webdriver.Firefox(executable_path=GeckoDriverManager().install())
103
104
105 floorsheet_dates = ['01/03/2016','01/04/2016']#, up to till date '01/10/2022']
106
107 for date in floorsheet_dates:
108 self.driver.get(
109 "https://merolagani.com/Floorsheet.aspx")
110
111 self.driver.find_element(By.XPATH, "//input[@name='ctl00$ContentPlaceHolder1$txtFloorsheetDateFilter']"
112 ).send_keys(date)
113 self.driver.find_element(By.XPATH, "(//a[@title='Search'])[3]").click()
114 total_length = self.driver.find_element(By.XPATH,
115 "//span[@id='ctl00_ContentPlaceHolder1_PagerControl2_litRecords']").text
116 z = int((total_length.split()[-1]).replace(']', ''))
117 for data in range(1, z + 1):
118 self.driver.find_element(By.XPATH, "(//a[@title='Page {}'])[2]".format(data)).click()
119 self.body = self.driver.page_source
120 self.url = self.driver.current_url
121
122 yield Request(url=self.url, callback=self.parse, dont_filter=True)
123
124 def parse(self, response, **kwargs):
125 print('test ok')
126 for value in response.xpath('//tbody/tr'):
127 print(value.css('td::text').extract()[1])
128 print("ok"*200)
129
Notice that I've used chrome so change it back to firefox like in your original code.
QUESTION
Python/Selenium web scrap how to find hidden src value from a links?
Asked 2022-Jan-16 at 02:28Scrapping links should be a simple feat, usually just grabbing the src
value of the a tag.
I recently came across this website (https://sunteccity.com.sg/promotions) where the href value of a tags of each item cannot be found, but the redirection still works. I'm trying to figure out a way to grab the items and their corresponding links. My typical python selenium code looks something as such
1all_items = bot.find_elements_by_class_name('thumb-img')
2for promo in all_items:
3 a = promo.find_elements_by_tag_name("a")
4 print("a[0]: ", a[0].get_attribute("href"))
5
However, I can't seem to retrieve any href
, onclick
attributes, and I'm wondering if this is even possible. I noticed that I couldn't do a right-click, open link in new tab as well.
Are there any ways around getting the links of all these items?
Edit: Are there any ways to retrieve all the links of the items on the pages?
i.e.
1all_items = bot.find_elements_by_class_name('thumb-img')
2for promo in all_items:
3 a = promo.find_elements_by_tag_name("a")
4 print("a[0]: ", a[0].get_attribute("href"))
5https://sunteccity.com.sg/promotions/724
6https://sunteccity.com.sg/promotions/731
7https://sunteccity.com.sg/promotions/751
8https://sunteccity.com.sg/promotions/752
9https://sunteccity.com.sg/promotions/754
10https://sunteccity.com.sg/promotions/280
11...
12
ANSWER
Answered 2022-Jan-15 at 19:47You are using a wrong locator. It brings you a lot of irrelevant elements.
Instead of find_elements_by_class_name('thumb-img')
please try find_elements_by_css_selector('.collections-page .thumb-img')
so your code will be
1all_items = bot.find_elements_by_class_name('thumb-img')
2for promo in all_items:
3 a = promo.find_elements_by_tag_name("a")
4 print("a[0]: ", a[0].get_attribute("href"))
5https://sunteccity.com.sg/promotions/724
6https://sunteccity.com.sg/promotions/731
7https://sunteccity.com.sg/promotions/751
8https://sunteccity.com.sg/promotions/752
9https://sunteccity.com.sg/promotions/754
10https://sunteccity.com.sg/promotions/280
11...
12all_items = bot.find_elements_by_css_selector('.collections-page .thumb-img')
13for promo in all_items:
14 a = promo.find_elements_by_tag_name("a")
15 print("a[0]: ", a[0].get_attribute("href"))
16
You can also get the desired links directly by .collections-page .thumb-img a
locator so that your code could be:
1all_items = bot.find_elements_by_class_name('thumb-img')
2for promo in all_items:
3 a = promo.find_elements_by_tag_name("a")
4 print("a[0]: ", a[0].get_attribute("href"))
5https://sunteccity.com.sg/promotions/724
6https://sunteccity.com.sg/promotions/731
7https://sunteccity.com.sg/promotions/751
8https://sunteccity.com.sg/promotions/752
9https://sunteccity.com.sg/promotions/754
10https://sunteccity.com.sg/promotions/280
11...
12all_items = bot.find_elements_by_css_selector('.collections-page .thumb-img')
13for promo in all_items:
14 a = promo.find_elements_by_tag_name("a")
15 print("a[0]: ", a[0].get_attribute("href"))
16links = bot.find_elements_by_css_selector('.collections-page .thumb-img a')
17for link in links:
18 print(link.get_attribute("href"))
19
QUESTION
Efficient code for custom color formatting in tkinter python
Asked 2022-Jan-11 at 14:31[Editing this question completely] Thank you , for those who helped in building the Periodic Table successfully . As I completed it , I tried to link it with another of my project E-Search
, which acts like Google and fetches answers , except that it will fetch me the data of the Periodic Table .
But , I got a problem - not with the searching but with the layout . I'm trying to layout the x-scrollbar in my canvas which will display results regarding the search . However , it is not properly done . Can anyone please help ?
Below here is my code :
1import tkinter as tk
2import PT
3
4root = tk.Tk()
5root.attributes('-fullscreen', True)
6root.config(bg='black')
7
8tk.Button(root, text='EXIT', command=root.destroy).place(x=0, y=0)
9
10elementals = PT.the_element_list
11
12search = tk.StringVar()
13
14search_entry = tk.Entry(root, textvariable=search)
15search_entry.place(relx=0.3, rely=0.3)
16
17
18def search_engine():
19
20 results = 0
21 var1 = 0
22
23 texts = ["Name : ", "Atomic No. : ", "Atomic Mass : ", "Block : ", "Group No. : ", "Period No. : ", "Type : ", "State : ", "Density : ", "Electronegativity : "]
24
25 scroll = tk.Scrollbar(root, orient="horizontal")
26 scroll.place(relx=0.05, rely=0.44, width=1000)
27
28 grand_canvas = tk.Canvas(root, bg='black', xscrollcommand=scroll.set)
29 grand_canvas.pack(fill="x", padx=20, pady=(0,40), side=tk.BOTTOM)
30
31
32 for i in elementals:
33 if search.get() in i or search.get() in str(i):
34 canvas1 = tk.Canvas(grand_canvas, bg='black', width=200, height=200)
35 canvas1.place(relx=0.02+results*0.18, rely=0.1)
36 results += 1
37 for x in range(10):
38 tk.Label(canvas1, text=f"{texts[x]}{i[x]}", bg='black', fg='white').place(relx=0.05, rely=0.08+var1*0.08)
39 var1 += 1
40 var1 = 0
41
42 scroll.config(command=grand_canvas.xview)
43
44 tk.Label(root, text=f"Number of resuts : {results}", bg='black', fg='white').place(relx=0.7, rely=0.3)
45
46tk.Button(root, text='Search', command=search_engine).place(relx=0.5, rely=0.3)
47
48root.mainloop()
49
50
And my Periodic Table Project , from where I extract data [Please name the file of this project as PT.py , then the code given above will work] .
1import tkinter as tk
2import PT
3
4root = tk.Tk()
5root.attributes('-fullscreen', True)
6root.config(bg='black')
7
8tk.Button(root, text='EXIT', command=root.destroy).place(x=0, y=0)
9
10elementals = PT.the_element_list
11
12search = tk.StringVar()
13
14search_entry = tk.Entry(root, textvariable=search)
15search_entry.place(relx=0.3, rely=0.3)
16
17
18def search_engine():
19
20 results = 0
21 var1 = 0
22
23 texts = ["Name : ", "Atomic No. : ", "Atomic Mass : ", "Block : ", "Group No. : ", "Period No. : ", "Type : ", "State : ", "Density : ", "Electronegativity : "]
24
25 scroll = tk.Scrollbar(root, orient="horizontal")
26 scroll.place(relx=0.05, rely=0.44, width=1000)
27
28 grand_canvas = tk.Canvas(root, bg='black', xscrollcommand=scroll.set)
29 grand_canvas.pack(fill="x", padx=20, pady=(0,40), side=tk.BOTTOM)
30
31
32 for i in elementals:
33 if search.get() in i or search.get() in str(i):
34 canvas1 = tk.Canvas(grand_canvas, bg='black', width=200, height=200)
35 canvas1.place(relx=0.02+results*0.18, rely=0.1)
36 results += 1
37 for x in range(10):
38 tk.Label(canvas1, text=f"{texts[x]}{i[x]}", bg='black', fg='white').place(relx=0.05, rely=0.08+var1*0.08)
39 var1 += 1
40 var1 = 0
41
42 scroll.config(command=grand_canvas.xview)
43
44 tk.Label(root, text=f"Number of resuts : {results}", bg='black', fg='white').place(relx=0.7, rely=0.3)
45
46tk.Button(root, text='Search', command=search_engine).place(relx=0.5, rely=0.3)
47
48root.mainloop()
49
50import tkinter as tk
51from functools import partial
52
53
54the_element_list = [['Hydrogen',1,'Non Metal',1,1,'s',1.01,'Gaseous',0.08,2.2],#H
55 ['Helium',2,'Noble Gas',18,1,'s',4.00,'Gaseous',0.18,'Unavailable'],#He
56
57 ['Lithium',3,'Alkaline Metal',1,2,'s',6.94,'Solid',0.53,0.98],#Li
58 ['Beryllium',4,'Alkaline Earth Metal',2,2,'s',9.01,'Solid',1.84,1.57],#Be
59 ['Boron',5,'Metalloid',13,2,'p',10.81,'Solid',2.46,2.04],#B
60 ['Carbon',6,'Non Metal',14,2,'p',12.01,'Solid',2.26,2.55],#C
61 ['Nitrogen',7,'Non Metal',15,2,'p',14.00,'Gaseous',1.17,3.04],#N
62 ['Oxygen',8,'Non Metal',16,2,'p',15.99,'Gaseous',1.43,3.44],#O
63 ['Fluorine',9,'Halogen',17,2,'p',18.99,'Gaseous',1.70,3.98],#F
64 ['Neon',10,'Noble Gas',18,2,'p',20.17,'Gaseous',0.90,'Unavailable'],#Ne
65
66 ['Sodium',11,'Alkaline Metal',1,3,'s',22.99,'Solid',0.97,0.93],#Na
67 ['Magnesium',12,'Alkaline Earth Metal',2,3,'s',24.31,'Solid',1.74,1.31],#Mg
68 ['Aluminium',13,'Metal',13,3,'p',26.98,'Solid',2.69,1.61],#Al
69 ['Silicon',14,'Metalloid',14,3,'p',28.08,'Solid',2.34,1.90],#Si
70 ['Phosphorus',15,'Non Metal',15,3,'p',30.97,'Solid',2.4,2.19],#P
71 ['Sulphur',16,'Non Metal',16,3,'p',32.06,'Solid',2.07,2.58],#S
72 ['Chlorine',17,'Halogen',17,3,'p',35.45,'Gaseous',3.22,3.16],#Cl
73 ['Argon',18,'Noble Gas',18,3,'p',39.95,'Gaseous',1.78,'Unavailable'],#Ar
74
75 ['Potassium',19,'Alkaline Metal',1,4,'s',39.09,'Solid',0.86,0.82],#K
76 ['Calicium',20,'Alkaline Earth Metal',2,4,'s',40.08,'Solid',1.55,1.00],#Ca
77 ['Scandium',21,'Transition Metal',3,4,'d',44.96,'Solid',2.99,1.36],#Sc
78 ['Titanium',22,'Transition Metal',4,4,'d',47.87,'Solid',4.5,1.54],#Ti
79 ['Vanadium',23,'Transition Metal',5,4,'d',50.94,'Solid',6.11,1.63],#V
80 ['Chromium',24,'Transition Metal',6,4,'d',51.99,'Solid',7.14,1.66],#Cr
81 ['Manganese',25,'Transition Metal',7,4,'d',54.94,'Solid',7.43,1.55],#Mn
82 ['Iron',26,'Transition Metal',8,4,'d',55.85,'Solid',7.87,1.83],#Fe
83 ['Cobalt',27,'Transition Metal',9,4,'d',58.93,'Solid',8.90,1.88],#Co
84 ['Nickel',28,'Transition Metal',10,4,'d',58.69,'Solid',8.90,1.91],#Ni
85 ['Copper',29,'Transition Metal',11,4,'d',63.54,'Solid',8.92,1.90],#Cu
86 ['Zinc',30,'Transition Metal',12,4,'d',65.38,'Solid',7.14,1.65],#Zn
87 ['Gallium',31,'Metal',13,4,'p',69.72,'Solid',5.90,1.81],#Ga
88 ['Germanium',32,'Metalloid',14,4,'p',72.63,'Solid',5.32,2.01],#Ge
89 ['Arsenic',33,'Metalloid',15,4,'p',74.92,'Solid',5.73,2.18],#As
90 ['Selenium',34,'Metalloid',16,4,'p',78.97,'Solid',4.82,2.55],#Se
91 ['Bromine',35,'Halogen',17,4,'p',79.90,'Liquid',3.12,2.96],#Br
92 ['Krypton',36,'Noble Gas',18,4,'p',83.80,'Gaseous',3.75,3.00],#Kr
93
94 ['Rubidium',37,'Alkaline Metal',1,5,'s',85.47,'Solid',1.53,0.82],#Rb
95 ['Strontium',38,'Alkaline Earth Metal',2,5,'s',87.62,'Solid',2.63,0.95],#Sr
96 ['Yttrium',39,'Transition Metal',3,5,'d',88.91,'Solid',4.47,1.22],#Y
97 ['Zirconium',40,'Transition Metal',4,5,'d',91.22,'Solid',6.50,1.33],#Zr
98 ['Niobium',41,'Transition Metal',5,5,'d',92.90,'Solid',8.57,1.6],#Nb
99 ['Molybednium',42,'Transition Metal',6,5,'d',95.95,'Solid',10.28,2.16],#Mo
100 ['Technetium',43,'Transition Metal',7,5,'d',98.90,'Solid',11.5,1.9],#Tc
101 ['Ruthenium',44,'Transition Metal',8,5,'d',101.07,'Solid',12.37,2.2],#Ru
102 ['Rhodium',45,'Transition Metal',9,5,'d',102.90,'Solid',12.38,2.28],#Rh
103 ['Palladium',46,'Transition Metal',10,5,'d',106.42,'Solid',11.99,2.20],#Pd
104 ['ilver',47,'Transition Metal',11,5,'d',107.87,'Solid',10.49,1.93],#Ag
105 ['Cadmium',48,'Transition Metal',12,5,'d',112.41,'Solid',8.65,1.69],#Cd
106 ['Indium',49,'Metal',13,5,'p',114.82,'Solid',7.31,1.78],#In
107 ['Tin',50,'Metal',14,5,'p',118.71,'Solid',5.77,1.96],#Sn
108 ['Antimony',51,'Metalloid',15,5,'p',121.76,'Solid',6.70,2.05],#Sb
109 ['Tellurium',52,'Metalloid',16,5,'p',127.60,'Solid',6.24,2.10],#Te
110 ['Iodine',53,'Halogen',17,5,'p',126.90,'Solid',4.94,2.66],#I
111 ['Xenon',54,'Noble Gas',18,5,'p',131.29,'Gaseous',5.90,2.6],#Xe
112
113 ['Caesium',55,'Alkaline Metal',1,6,'s',132.91,'Solid',1.90,0.79],#Cs
114 ['Barium',56,'Alkaline Earth Metal',2,6,'s',137.33,'Solid',3.62,0.89],#Ba
115
116 ['Lanthanum',57,'Transition Metal',3,6,'d',138.90,'Solid',6.17,1.1],#La
117 ['Cerium',58,'Lanthanide','La',6,'f',140.12,'Solid',6.77,1.12],#Ce
118 ['Praseodymium',59,'Lanthanide','La',6,'f',140.91,'Solid',6.48,1.13],#Pr
119 ['Neodymium',60,'Lanthanide','La',6,'f',144.24,'Solid',7.00,1.14],#Nd
120 ['Promethium',61,'Lanthanide','La',6,'f',146.91,'Solid',7.2,'Unavailable.'],#Pm
121 ['Samarium',62,'Lanthanide','La',6,'f',150.36,'Solid',7.54,1.17],#Sm
122 ['Europium',63,'Lanthanide','La',6,'f',151.96,'Solid',5.25,'Unavailable'],#Eu
123 ['Gadolinium',64,'Lanthanide','La',6,'f',157.25,'Solid',7.89,1.20],#Gd
124 ['Terbium',65,'Lanthanide','La',6,'f',158.93,'Solid',8.25,'Unavailable'],#Tb
125 ['Dysprosium',66,'Lanthanide','La',6,'f',162.50,'Solid',8.56,1.22],#Dy
126 ['Holmium',67,'Lanthanide','La',6,'f',164.93,'Solid',8.78,1.23],#Ho
127 ['Erbium',68,'Lanthanide','La',6,'f',167.26,'Solid',9.05,1.24],#Er
128 ['Thulium',69,'Lanthanide','La',6,'f',168.93,'Solid',9.32,1.25],#Tm
129 ['Ytterbium',70,'Lanthanide','La',6,'f',173.05,'Solid',6.97,'Unavailable'],#Yb
130 ['Lutetium',71,'Lanthanide','La',6,'f',174.97,'Solid',9.84,1.27],#Lu
131
132 ['Hafnium',72,'Transition Metal',4,6,'d',178.49,'Solid',13.28,1.3],#Hf
133 ['Tantalum',73,'Transition Metal',5,6,'d',180.95,'Solid',16.65,1.5],#Ta
134 ['Tungsten',74,'Transition Metal',6,6,'d',183.84,'Solid',19.25,2.36],#W
135 ['Rhenium',75,'Transition Metal',7,6,'d',186.21,'Solid',21.00,1.9],#Re
136 ['Osmium',76,'Transition Metal',8,6,'d',190.23,'Solid',22.59,2.2],#Os
137 ['Irdium',77,'Transition Metal',9,6,'d',192.22,'Solid',22.56,2.2],#Ir
138 ['Platinum',78,'Transition Metal',10,6,'d',195.08,'Solid',21.45,2.2],#Pt
139 ['Gold',79,'Transition Metal',11,6,'d',196.97,'Solid',19.32,2.54],#Au
140 ['Mercury',80,'Transition Metal',12,6,'d',200.59,'Liquid',13.55,2.00],#Hg
141 ['Thalium',81,'Metal',13,6,'p',204.38,'Solid',11.85,1.62],#Tl
142 ['Lead',82,'Metal',14,6,'p',207.20,'Solid',11.34,2.33],#Pb
143 ['Bismuth',83,'Metal',15,6,'p',208.98,'Solid',9.78,2.02],#Bi
144 ['Polonium',84,'Metal',16,6,'p',209.98,'Solid',9.20,2.0],#Po
145 ['Astatine',85,'Halogen',17,6,'p',209.99,'Solid','Unavailable',2.2],#At
146 ['Radon',86,'Noble Gas',18,6,'p',222.00,'Gaseous',9.73,'Unavailable'],#Rn
147
148 ['Francium',87,'Alkaline Metal',1,7,'s',223.02,'Solid','Unavailable',0.7],#Fr
149 ['Radium',88,'Alkaline Earth Metal',2,7,'s',226.03,'Solid',5.5,0.9],#Ra
150
151 ['Actinium',89,'Transition Metal',3,7,'d',227.03,'Solid',10.07,1.1],#Ac
152 ['Thorium',90,'Actinide','Ac',7,'f',232.04,'Solid',11.72,1.3],#Th
153 ['Protactinium',91,'Actinide','Ac',7,'f',231.04,'Solid',15.37,1.5],#Pa
154 ['Uranium',92,'Actinide','Ac',7,'f',238.03,'Solid',19.16,1.38],#U
155 ['Neptunium',93,'Actinide','Ac',7,'f',237.05,'Solid',20.45,1.36],#Np
156 ['Plutonium',94,'Actinide','Ac',7,'f',244.06,'Solid',19.82,1.28],#Pu
157 ['Americium',95,'Actinide','Ac',7,'f',243.06,'Solid',13.67,1.3],#Am
158 ['Curium',96,'Actinide','Ac',7,'f',247.07,'Solid',13.51,1.3],#Cm
159 ['Berkelium',97,'Actinide','Ac',7,'f',247,'Solid',14.78,1.3],#Bk
160 ['Californium',98,'Actinide','Ac',7,'f',251,'Solid',15.1,1.3],#Cf
161 ['Einsteinium',99,'Actinide','Ac',7,'f',252,'Solid',8.84,'Unavailable'],#Es
162 ['Fermium',100,'Actinide','Ac',7,'f',257.10,'Solid','Unavailable','Unavailable'],#Fm
163 ['Medelevium',101,'Actinide','Ac',7,'f',258,'Solid','Unavailable','Unavailable'],#Md
164 ['Nobelium',102,'Actinide','Ac',7,'f',259,'Solid','Unavailable.','Unavailable'],#No
165 ['Lawrencium',103,'Actinide','Ac',7,'f',266,'Solid','Unavailable','Unavailable'],#Lr
166
167 ['Rutherfordium',104,'Transition Metal',4,7,'d',261.11,'Solid',17.00,'Unavailable'],#Rf
168 ['Dubnium',105,'Transition Metal',5,7,'d',262.11,'Unavailable','Unavailable','Unavailable'],#Db
169 ['Seaborgium',106,'Transition Metal',6,7,'d',263.12,'Unavailable','Unavailable','Unavailable'],#Sg
170 ['Bohrium',107,'Transition Metal',7,7,'d',262.12,'Unavailable','Unavailable','Unavailable'],#Bh
171 ['Hassium',108,'Transition Metal',8,7,'d',265,'Unavailable','Unavailable','Unavailable'],#Hs
172 ['Meitnerium',109,'Unknown',9,7,'d',268,'Unavailable','Unavailable','Unavailable'],#Mt
173 ['Darmstadtium',110,'Unknown',10,7,'d',281,'Unavailable','Unavailable','Unavailable'],#Ds
174 ['Roentgenium',111,'Unknown',11,7,'d',280,'Unavailable','Unavailable','Unavailable'],#Rg
175 ['Copernicium',112,'Unknown',12,7,'d',277,'Unavailable','Unavailable','Unavailable'],#Cn
176 ['Nihonium',113,'Unknown',13,7,'p',287,'Unavailable','Unavailable','Unavailable'],#Nh
177 ['Flerovium',114,'Unknown',14,7,'p',289,'Unavailable','Unavailable','Unavailable'],#Fl
178 ['Moscovium',115,'Unknown',15,7,'p',288,'Unavailable','Unavailable','Unavailable'],#Mc
179 ['Livermorium',116,'Unknown',16,7,'p',293,'Unavailable','Unavailable','Unavailable'],#Lv
180 ['Tennessine',117,'Unknown',17,7,'p',292,'Unavailable','Unavailable','Unavailable'],#Ts
181 ['Oganesson',118,'Unknown',18,7,'p',294,'Solid',6.6,'Unavailable']]#Og
182
183
184if __name__ == '__main__': # Listing the information of elements
185
186 group_no_of_elements = [1] ; period_no_of_elements = [1] ; atomic_mass_of_elements = [1.01] ; block_of_elements = ['s'] ; name_of_elements = ['Hydrogen'] ; atomic_number_of_elements = [1] ; type_of_elements = ['Non Metal'] ; state_of_elements = ['Gaseous'] ; density_of_elements = [0.08] ; electronegativity_of_elements = [2.2]
187
188 group_no_of_elements_sec = [] ; period_no_of_elements_sec = [] ; atomic_mass_of_elements_sec = [] ; block_of_elements_sec = [] ; name_of_elements_sec = [] ; atomic_number_of_elements_sec = [] ; type_of_elements_sec = [] ; state_of_elements_sec = [] ; density_of_elements_sec = [] ; electronegativity_of_elements_sec = []
189
190
191 def add_to_list(a,b,c):
192
193 for i in range(a,b):
194 if c == ' ':
195 atomic_number_of_elements.append(" ")
196 name_of_elements.append(" ")
197 atomic_mass_of_elements.append(" ")
198 block_of_elements.append(" ")
199 group_no_of_elements.append(" ")
200 period_no_of_elements.append(" ")
201 type_of_elements.append(" ")
202 state_of_elements.append(" ")
203 density_of_elements.append(" ")
204 electronegativity_of_elements.append(" ")
205
206 elif c == 1:
207 name_of_elements.append(the_element_list[i][0])
208 atomic_number_of_elements.append(the_element_list[i][1])
209 type_of_elements.append(the_element_list[i][2])
210 group_no_of_elements.append(the_element_list[i][3])
211 period_no_of_elements.append(the_element_list[i][4])
212 block_of_elements.append(the_element_list[i][5])
213 atomic_mass_of_elements.append(the_element_list[i][6])
214 state_of_elements.append(the_element_list[i][7])
215 density_of_elements.append(the_element_list[i][8])
216 electronegativity_of_elements.append(the_element_list[i][9])
217
218 elif c == 2:
219 name_of_elements_sec.append(the_element_list[i][0])
220 atomic_number_of_elements_sec.append(the_element_list[i][1])
221 type_of_elements_sec.append(the_element_list[i][2])
222 group_no_of_elements_sec.append(the_element_list[i][3])
223 period_no_of_elements_sec.append(the_element_list[i][4])
224 block_of_elements_sec.append(the_element_list[i][5])
225 atomic_mass_of_elements_sec.append(the_element_list[i][6])
226 state_of_elements_sec.append(the_element_list[i][7])
227 density_of_elements_sec.append(the_element_list[i][8])
228 electronegativity_of_elements_sec.append(the_element_list[i][9])
229
230
231 add_to_list(0,16,' ')
232 add_to_list(1,4,1)
233 add_to_list(0,10,' ')
234 add_to_list(4,12,1)
235 add_to_list(0,10,' ')
236 add_to_list(12,56,1)
237 add_to_list(0,1,' ')
238 add_to_list(71,88,1)
239 add_to_list(0,1,' ')
240 add_to_list(103,118,1)
241 add_to_list(56,71,2)
242 add_to_list(88,103,2)
243
244
245if __name__ == '__main__': # Variables -- Toplevel Window's Names
246
247 tk_window = []
248 for i in range(0,126):
249 tk_window.append(i)
250
251 tk_window_2 = []
252 for i in range(0,30):
253 tk_window_2.append(i)
254
255
256if __name__ == '__main__': # Variables -- Symbols of elements in the Periodic Table
257
258 period_1 = ['H' ,'','','','','','','','','','','','','','','','','He']
259 period_2 = ['Li','Be','','','','','','','','','','','B','C','N','O','F','Ne']
260 period_3 = ['Na','Mg','','','','','','','','','','','Al','Si','P','S','Cl','Ar']
261 period_4 = """K Ca Sc Ti V Cr Mn Fe Co Ni Cu Zn Ga Ge As Se Br Kr""".split(" ")
262 period_5 = """Rb Sr Y Zr Nb Mo Tc Ru Rh Pd Ag Cd In Sn Sb Te I Xe""".split(" ")
263 period_6 = """Cs Ba * Hf Ta W Re Os Ir Pt Au Hg Tl Pb Bi Po At Rn""".split(" ")
264 period_7 = """Fr Ra ** Rf D Sg Bh Hs Mt Ds Rg Cn Nh Fl Mc Lv Ts Og""".split(" ")
265
266 period_6a = """La Ce Pr Nd Pm Sm Eu Gd Tb Dy Ho Er Tm Yb Lu""".split(" ")
267 period_7a = """Ac Th Pa U Np Pu Am Cm Bk Cf Es Fm Md No Lr""".split(" ")
268
269 # Making a list of main elements and secondary elements
270 main = period_1 + period_2 + period_3 + period_4 + period_5 + period_6 + period_7
271 sec = period_6a + period_7a
272
273
274if __name__ == '__main__': # Variables -- Colours for each group of simliar elements in the Periodic Table
275
276 # Colors for each group
277 non_m_col = '#feab90'
278 alk_m_col = '#ffe0b2'
279 alk_ea_col = '#fecc81'
280 trans_m_col = '#d2c4e8'
281 halogen_col = '#a4d7a7'
282 metals_col = '#feab90'
283 noble_g_col = '#fefffe'
284 act_col = '#b2e5fd'
285 rare_m_col = '#e7ee9a'
286 plain_but_col = 'grey'
287
288
289if __name__ == '__main__': # Using tkinter to display a Periodic Table of Elements
290
291 root = tk.Tk()
292 root.attributes('-fullscreen', True)
293 root.config(bg='purple')
294
295 tk.Label(root, text="Periodic Table of Elements", bg='purple', fg='white', font=['Bookman Old Style', 40, 'bold', 'underline']).place(relx=0.15, rely=0.02)
296
297
298 if __name__ == '__main__': # Frames for the Periodic Table
299
300 # Frame for the entire table
301 period_tab = tk.Frame(root, bg='grey', highlightbackground='black', highlightthickness=20)
302 period_tab.pack(side=tk.BOTTOM, pady=(0,50))
303
304 # Frame for the main elements only
305 main_elem = tk.Frame(period_tab)
306 main_elem.pack(padx=20, pady=20)
307
308 # Frame for the secondary elements only
309 sec_elem = tk.Frame(period_tab)
310 sec_elem.pack(pady=20, padx=20)
311
312
313 if __name__ == '__main__': # Function which creates a window of info for each element
314
315 def PT(window, name, symbol, atom_no, atom_mass, block, group, period, type, state, density, electronegativity):
316 if atom_no == ' ':
317 pass
318 else:
319 window = tk.Toplevel(root)
320 window.geometry('400x400')
321 window.config(bg='black')
322
323 tk.Label(window, text=name, bg='black', fg='white').place(relx=0.3, rely=0.1)
324
325 tk.Label(window, text=f"Symbol : {symbol}", bg='black', fg='white').place(relx=0.05, rely=0.3)
326 tk.Label(window, text=f"Atomic Number : {atom_no}", bg='black', fg='white').place(relx=0.05, rely=0.35)
327 tk.Label(window, text=f"Atomic Mass : {atom_mass}", bg='black', fg='white').place(relx=0.05, rely=0.4)
328 tk.Label(window, text=f"Block : {block}", bg='black', fg='white').place(relx=0.05, rely=0.45)
329 tk.Label(window, text=f"Group Number : {group}", bg='black', fg='white').place(relx=0.05, rely=0.5)
330 tk.Label(window, text=f"Period Number : {period}", bg='black', fg='white').place(relx=0.05, rely=0.55)
331 tk.Label(window, text=f"Type of element : {type}", bg='black', fg='white').place(relx=0.05, rely=0.6)
332 tk.Label(window, text=f"State of element : {state}", bg='black', fg='white').place(relx=0.05, rely=0.65)
333 tk.Label(window, text=f"Density : {density}", bg='black', fg='white').place(relx=0.05, rely=0.7)
334 tk.Label(window, text=f"Electronegativity : {electronegativity}", bg='black', fg='white').place(relx=0.05, rely=0.75)
335
336
337 if __name__ == '__main__': # Creating buttons for each element in the Periodic Table
338
339 # Creating a 7x18 table of buttons and appending it to a 2D python list for main elements
340 buttons = []
341 for i in range(7):
342 temp = []
343 for j in range(18):
344 but = tk.Button(main_elem,text=main[18*i+j],width=8,bg='#f0f0f0', command=partial(PT, tk_window[18*i+j], name_of_elements[18*i+j], main[18*i+j], atomic_number_of_elements[18*i+j], atomic_mass_of_elements[18*i+j], block_of_elements[18*i+j], group_no_of_elements[18*i+j], period_no_of_elements[18*i+j], type_of_elements[18*i+j], state_of_elements[18*i+j], density_of_elements[18*i+j], electronegativity_of_elements[18*i+j]))
345 but.grid(row=i,column=j)
346 temp.append(but)
347 buttons.append(temp)
348
349 # Creating a 2x15 table of buttons for secondary elements
350 for i in range(2):
351 for j in range(15):
352 if i == 0: # If row 1 then different color
353 tk.Button(sec_elem,text=sec[15*i+j],width=8,bg=rare_m_col, command=partial(PT, tk_window_2[15*i+j], name_of_elements_sec[15*i+j], sec[15*i+j], atomic_number_of_elements_sec[15*i+j], atomic_mass_of_elements_sec[15*i+j], block_of_elements_sec[15*i+j], group_no_of_elements_sec[15*i+j], period_no_of_elements_sec[15*i+j], type_of_elements_sec[15*i+j], state_of_elements_sec[15*i+j], density_of_elements_sec[15*i+j], electronegativity_of_elements_sec[15*i+j])).grid(row=i,column=j)
354 else:
355 tk.Button(sec_elem,text=sec[15*i+j],width=8,bg=act_col, command=partial(PT, tk_window_2[15*i+j], name_of_elements_sec[15*i+j], sec[15*i+j], atomic_number_of_elements_sec[15*i+j], atomic_mass_of_elements_sec[15*i+j], block_of_elements_sec[15*i+j], group_no_of_elements_sec[15*i+j], period_no_of_elements_sec[15*i+j], type_of_elements_sec[15*i+j], state_of_elements_sec[15*i+j], density_of_elements_sec[15*i+j], electronegativity_of_elements_sec[15*i+j])).grid(row=i,column=j)
356
357
358 if __name__ == '__main__': # Setting colours for each button
359
360 # Manually pick out main elements from the table
361 non_metals = buttons[0][0],buttons[1][12:16],buttons[2][13:16],buttons[3][14:16],buttons[4][15]
362 alk_metals = [row[0] for row in buttons[1:]]
363 alk_ea_metals = [row[1] for row in buttons[1:]]
364 halogens = [row[16] for row in buttons[1:]]
365 noble_gases = [row[-1] for row in buttons[:]]
366 transition_met = [buttons[x][3:12] for x in range(3,7)]
367 metals = buttons[6][12:16],buttons[5][12:16],buttons[4][12:15],buttons[3][12:14],buttons[2][12]
368 rare_metals = [row[2] for row in buttons[3:6]]
369 actinoid = buttons[-1][2]
370 plain_but = buttons[0][1:-1],buttons[1][2:12],buttons[2][2:12]
371
372 # Change colors for those main element buttons
373 actinoid['bg'] = act_col
374 for i in alk_metals:
375 i['bg'] = alk_m_col
376 for i in alk_ea_metals:
377 i['bg'] = alk_ea_col
378 for i in halogens:
379 i['bg'] = halogen_col
380 for i in noble_gases:
381 i['bg'] = noble_g_col
382 for i in rare_metals:
383 i['bg'] = rare_m_col
384
385 for i in transition_met:
386 for j in i:
387 j['bg'] = trans_m_col
388
389 for i in plain_but:
390 for j in i:
391 j['bg'] = plain_but_col
392
393 for i in non_metals:
394 if isinstance(i,list):
395 for j in i:
396 j.config(bg=non_m_col)
397 else:
398 i.config(bg=non_m_col)
399
400 for i in metals:
401 if isinstance(i,list):
402 for j in i:
403 j.config(bg=metals_col)
404 else:
405 i.config(bg=metals_col)
406
407 for i in plain_but:
408 for j in i:
409 j['relief'] = 'flat'
410
411
412 if __name__ == '__main__': # Creating a frame for categorizing elements on basis of their colours
413 legends_frame = tk.Canvas(root, bg='black', width=200, height=250)
414
415 tk.Label(legends_frame, text='Categories', bg='black', fg='white', font=['Bookman Old Style', 10, 'underline']).place(relx=0.25, rely=0.03)
416
417 labels = ['Actinides', 'Alkali Metals', 'Alkali Earth Metals', 'Halogens', 'Lanthanides', 'Metalloids', 'Noble Gases', 'Non Metals', 'Transition Metals']
418 colours = [act_col, alk_m_col, alk_ea_col, halogen_col, rare_m_col, metals_col, noble_g_col, non_m_col, trans_m_col]
419
420 for i in range(0,9):
421 tk.Label(legends_frame, text=labels[i], bg='black', fg=colours[i]).place(relx=0.4, rely=0.16+i*0.09)
422 tk.Canvas(legends_frame, bg=colours[i], width=32, height=12, borderwidth=0).place(relx=0.1, rely=0.16+i*0.09)
423
424 legends_frame.place(relx=0.8, rely=0.05)
425
426
427 tk.Button(root,text='EXIT',command=root.destroy).place(x=10, y=10)
428
429 root.mainloop()
430
Further Notes : If anyone could suggest me some tips through which I can write better codes , I would be grateful to him/her .
ANSWER
Answered 2021-Dec-29 at 20:33I rewrote your code with some better ways to create table. My idea was to pick out the buttons that fell onto a range of type and then loop through those buttons and change its color to those type.
1import tkinter as tk
2import PT
3
4root = tk.Tk()
5root.attributes('-fullscreen', True)
6root.config(bg='black')
7
8tk.Button(root, text='EXIT', command=root.destroy).place(x=0, y=0)
9
10elementals = PT.the_element_list
11
12search = tk.StringVar()
13
14search_entry = tk.Entry(root, textvariable=search)
15search_entry.place(relx=0.3, rely=0.3)
16
17
18def search_engine():
19
20 results = 0
21 var1 = 0
22
23 texts = ["Name : ", "Atomic No. : ", "Atomic Mass : ", "Block : ", "Group No. : ", "Period No. : ", "Type : ", "State : ", "Density : ", "Electronegativity : "]
24
25 scroll = tk.Scrollbar(root, orient="horizontal")
26 scroll.place(relx=0.05, rely=0.44, width=1000)
27
28 grand_canvas = tk.Canvas(root, bg='black', xscrollcommand=scroll.set)
29 grand_canvas.pack(fill="x", padx=20, pady=(0,40), side=tk.BOTTOM)
30
31
32 for i in elementals:
33 if search.get() in i or search.get() in str(i):
34 canvas1 = tk.Canvas(grand_canvas, bg='black', width=200, height=200)
35 canvas1.place(relx=0.02+results*0.18, rely=0.1)
36 results += 1
37 for x in range(10):
38 tk.Label(canvas1, text=f"{texts[x]}{i[x]}", bg='black', fg='white').place(relx=0.05, rely=0.08+var1*0.08)
39 var1 += 1
40 var1 = 0
41
42 scroll.config(command=grand_canvas.xview)
43
44 tk.Label(root, text=f"Number of resuts : {results}", bg='black', fg='white').place(relx=0.7, rely=0.3)
45
46tk.Button(root, text='Search', command=search_engine).place(relx=0.5, rely=0.3)
47
48root.mainloop()
49
50import tkinter as tk
51from functools import partial
52
53
54the_element_list = [['Hydrogen',1,'Non Metal',1,1,'s',1.01,'Gaseous',0.08,2.2],#H
55 ['Helium',2,'Noble Gas',18,1,'s',4.00,'Gaseous',0.18,'Unavailable'],#He
56
57 ['Lithium',3,'Alkaline Metal',1,2,'s',6.94,'Solid',0.53,0.98],#Li
58 ['Beryllium',4,'Alkaline Earth Metal',2,2,'s',9.01,'Solid',1.84,1.57],#Be
59 ['Boron',5,'Metalloid',13,2,'p',10.81,'Solid',2.46,2.04],#B
60 ['Carbon',6,'Non Metal',14,2,'p',12.01,'Solid',2.26,2.55],#C
61 ['Nitrogen',7,'Non Metal',15,2,'p',14.00,'Gaseous',1.17,3.04],#N
62 ['Oxygen',8,'Non Metal',16,2,'p',15.99,'Gaseous',1.43,3.44],#O
63 ['Fluorine',9,'Halogen',17,2,'p',18.99,'Gaseous',1.70,3.98],#F
64 ['Neon',10,'Noble Gas',18,2,'p',20.17,'Gaseous',0.90,'Unavailable'],#Ne
65
66 ['Sodium',11,'Alkaline Metal',1,3,'s',22.99,'Solid',0.97,0.93],#Na
67 ['Magnesium',12,'Alkaline Earth Metal',2,3,'s',24.31,'Solid',1.74,1.31],#Mg
68 ['Aluminium',13,'Metal',13,3,'p',26.98,'Solid',2.69,1.61],#Al
69 ['Silicon',14,'Metalloid',14,3,'p',28.08,'Solid',2.34,1.90],#Si
70 ['Phosphorus',15,'Non Metal',15,3,'p',30.97,'Solid',2.4,2.19],#P
71 ['Sulphur',16,'Non Metal',16,3,'p',32.06,'Solid',2.07,2.58],#S
72 ['Chlorine',17,'Halogen',17,3,'p',35.45,'Gaseous',3.22,3.16],#Cl
73 ['Argon',18,'Noble Gas',18,3,'p',39.95,'Gaseous',1.78,'Unavailable'],#Ar
74
75 ['Potassium',19,'Alkaline Metal',1,4,'s',39.09,'Solid',0.86,0.82],#K
76 ['Calicium',20,'Alkaline Earth Metal',2,4,'s',40.08,'Solid',1.55,1.00],#Ca
77 ['Scandium',21,'Transition Metal',3,4,'d',44.96,'Solid',2.99,1.36],#Sc
78 ['Titanium',22,'Transition Metal',4,4,'d',47.87,'Solid',4.5,1.54],#Ti
79 ['Vanadium',23,'Transition Metal',5,4,'d',50.94,'Solid',6.11,1.63],#V
80 ['Chromium',24,'Transition Metal',6,4,'d',51.99,'Solid',7.14,1.66],#Cr
81 ['Manganese',25,'Transition Metal',7,4,'d',54.94,'Solid',7.43,1.55],#Mn
82 ['Iron',26,'Transition Metal',8,4,'d',55.85,'Solid',7.87,1.83],#Fe
83 ['Cobalt',27,'Transition Metal',9,4,'d',58.93,'Solid',8.90,1.88],#Co
84 ['Nickel',28,'Transition Metal',10,4,'d',58.69,'Solid',8.90,1.91],#Ni
85 ['Copper',29,'Transition Metal',11,4,'d',63.54,'Solid',8.92,1.90],#Cu
86 ['Zinc',30,'Transition Metal',12,4,'d',65.38,'Solid',7.14,1.65],#Zn
87 ['Gallium',31,'Metal',13,4,'p',69.72,'Solid',5.90,1.81],#Ga
88 ['Germanium',32,'Metalloid',14,4,'p',72.63,'Solid',5.32,2.01],#Ge
89 ['Arsenic',33,'Metalloid',15,4,'p',74.92,'Solid',5.73,2.18],#As
90 ['Selenium',34,'Metalloid',16,4,'p',78.97,'Solid',4.82,2.55],#Se
91 ['Bromine',35,'Halogen',17,4,'p',79.90,'Liquid',3.12,2.96],#Br
92 ['Krypton',36,'Noble Gas',18,4,'p',83.80,'Gaseous',3.75,3.00],#Kr
93
94 ['Rubidium',37,'Alkaline Metal',1,5,'s',85.47,'Solid',1.53,0.82],#Rb
95 ['Strontium',38,'Alkaline Earth Metal',2,5,'s',87.62,'Solid',2.63,0.95],#Sr
96 ['Yttrium',39,'Transition Metal',3,5,'d',88.91,'Solid',4.47,1.22],#Y
97 ['Zirconium',40,'Transition Metal',4,5,'d',91.22,'Solid',6.50,1.33],#Zr
98 ['Niobium',41,'Transition Metal',5,5,'d',92.90,'Solid',8.57,1.6],#Nb
99 ['Molybednium',42,'Transition Metal',6,5,'d',95.95,'Solid',10.28,2.16],#Mo
100 ['Technetium',43,'Transition Metal',7,5,'d',98.90,'Solid',11.5,1.9],#Tc
101 ['Ruthenium',44,'Transition Metal',8,5,'d',101.07,'Solid',12.37,2.2],#Ru
102 ['Rhodium',45,'Transition Metal',9,5,'d',102.90,'Solid',12.38,2.28],#Rh
103 ['Palladium',46,'Transition Metal',10,5,'d',106.42,'Solid',11.99,2.20],#Pd
104 ['ilver',47,'Transition Metal',11,5,'d',107.87,'Solid',10.49,1.93],#Ag
105 ['Cadmium',48,'Transition Metal',12,5,'d',112.41,'Solid',8.65,1.69],#Cd
106 ['Indium',49,'Metal',13,5,'p',114.82,'Solid',7.31,1.78],#In
107 ['Tin',50,'Metal',14,5,'p',118.71,'Solid',5.77,1.96],#Sn
108 ['Antimony',51,'Metalloid',15,5,'p',121.76,'Solid',6.70,2.05],#Sb
109 ['Tellurium',52,'Metalloid',16,5,'p',127.60,'Solid',6.24,2.10],#Te
110 ['Iodine',53,'Halogen',17,5,'p',126.90,'Solid',4.94,2.66],#I
111 ['Xenon',54,'Noble Gas',18,5,'p',131.29,'Gaseous',5.90,2.6],#Xe
112
113 ['Caesium',55,'Alkaline Metal',1,6,'s',132.91,'Solid',1.90,0.79],#Cs
114 ['Barium',56,'Alkaline Earth Metal',2,6,'s',137.33,'Solid',3.62,0.89],#Ba
115
116 ['Lanthanum',57,'Transition Metal',3,6,'d',138.90,'Solid',6.17,1.1],#La
117 ['Cerium',58,'Lanthanide','La',6,'f',140.12,'Solid',6.77,1.12],#Ce
118 ['Praseodymium',59,'Lanthanide','La',6,'f',140.91,'Solid',6.48,1.13],#Pr
119 ['Neodymium',60,'Lanthanide','La',6,'f',144.24,'Solid',7.00,1.14],#Nd
120 ['Promethium',61,'Lanthanide','La',6,'f',146.91,'Solid',7.2,'Unavailable.'],#Pm
121 ['Samarium',62,'Lanthanide','La',6,'f',150.36,'Solid',7.54,1.17],#Sm
122 ['Europium',63,'Lanthanide','La',6,'f',151.96,'Solid',5.25,'Unavailable'],#Eu
123 ['Gadolinium',64,'Lanthanide','La',6,'f',157.25,'Solid',7.89,1.20],#Gd
124 ['Terbium',65,'Lanthanide','La',6,'f',158.93,'Solid',8.25,'Unavailable'],#Tb
125 ['Dysprosium',66,'Lanthanide','La',6,'f',162.50,'Solid',8.56,1.22],#Dy
126 ['Holmium',67,'Lanthanide','La',6,'f',164.93,'Solid',8.78,1.23],#Ho
127 ['Erbium',68,'Lanthanide','La',6,'f',167.26,'Solid',9.05,1.24],#Er
128 ['Thulium',69,'Lanthanide','La',6,'f',168.93,'Solid',9.32,1.25],#Tm
129 ['Ytterbium',70,'Lanthanide','La',6,'f',173.05,'Solid',6.97,'Unavailable'],#Yb
130 ['Lutetium',71,'Lanthanide','La',6,'f',174.97,'Solid',9.84,1.27],#Lu
131
132 ['Hafnium',72,'Transition Metal',4,6,'d',178.49,'Solid',13.28,1.3],#Hf
133 ['Tantalum',73,'Transition Metal',5,6,'d',180.95,'Solid',16.65,1.5],#Ta
134 ['Tungsten',74,'Transition Metal',6,6,'d',183.84,'Solid',19.25,2.36],#W
135 ['Rhenium',75,'Transition Metal',7,6,'d',186.21,'Solid',21.00,1.9],#Re
136 ['Osmium',76,'Transition Metal',8,6,'d',190.23,'Solid',22.59,2.2],#Os
137 ['Irdium',77,'Transition Metal',9,6,'d',192.22,'Solid',22.56,2.2],#Ir
138 ['Platinum',78,'Transition Metal',10,6,'d',195.08,'Solid',21.45,2.2],#Pt
139 ['Gold',79,'Transition Metal',11,6,'d',196.97,'Solid',19.32,2.54],#Au
140 ['Mercury',80,'Transition Metal',12,6,'d',200.59,'Liquid',13.55,2.00],#Hg
141 ['Thalium',81,'Metal',13,6,'p',204.38,'Solid',11.85,1.62],#Tl
142 ['Lead',82,'Metal',14,6,'p',207.20,'Solid',11.34,2.33],#Pb
143 ['Bismuth',83,'Metal',15,6,'p',208.98,'Solid',9.78,2.02],#Bi
144 ['Polonium',84,'Metal',16,6,'p',209.98,'Solid',9.20,2.0],#Po
145 ['Astatine',85,'Halogen',17,6,'p',209.99,'Solid','Unavailable',2.2],#At
146 ['Radon',86,'Noble Gas',18,6,'p',222.00,'Gaseous',9.73,'Unavailable'],#Rn
147
148 ['Francium',87,'Alkaline Metal',1,7,'s',223.02,'Solid','Unavailable',0.7],#Fr
149 ['Radium',88,'Alkaline Earth Metal',2,7,'s',226.03,'Solid',5.5,0.9],#Ra
150
151 ['Actinium',89,'Transition Metal',3,7,'d',227.03,'Solid',10.07,1.1],#Ac
152 ['Thorium',90,'Actinide','Ac',7,'f',232.04,'Solid',11.72,1.3],#Th
153 ['Protactinium',91,'Actinide','Ac',7,'f',231.04,'Solid',15.37,1.5],#Pa
154 ['Uranium',92,'Actinide','Ac',7,'f',238.03,'Solid',19.16,1.38],#U
155 ['Neptunium',93,'Actinide','Ac',7,'f',237.05,'Solid',20.45,1.36],#Np
156 ['Plutonium',94,'Actinide','Ac',7,'f',244.06,'Solid',19.82,1.28],#Pu
157 ['Americium',95,'Actinide','Ac',7,'f',243.06,'Solid',13.67,1.3],#Am
158 ['Curium',96,'Actinide','Ac',7,'f',247.07,'Solid',13.51,1.3],#Cm
159 ['Berkelium',97,'Actinide','Ac',7,'f',247,'Solid',14.78,1.3],#Bk
160 ['Californium',98,'Actinide','Ac',7,'f',251,'Solid',15.1,1.3],#Cf
161 ['Einsteinium',99,'Actinide','Ac',7,'f',252,'Solid',8.84,'Unavailable'],#Es
162 ['Fermium',100,'Actinide','Ac',7,'f',257.10,'Solid','Unavailable','Unavailable'],#Fm
163 ['Medelevium',101,'Actinide','Ac',7,'f',258,'Solid','Unavailable','Unavailable'],#Md
164 ['Nobelium',102,'Actinide','Ac',7,'f',259,'Solid','Unavailable.','Unavailable'],#No
165 ['Lawrencium',103,'Actinide','Ac',7,'f',266,'Solid','Unavailable','Unavailable'],#Lr
166
167 ['Rutherfordium',104,'Transition Metal',4,7,'d',261.11,'Solid',17.00,'Unavailable'],#Rf
168 ['Dubnium',105,'Transition Metal',5,7,'d',262.11,'Unavailable','Unavailable','Unavailable'],#Db
169 ['Seaborgium',106,'Transition Metal',6,7,'d',263.12,'Unavailable','Unavailable','Unavailable'],#Sg
170 ['Bohrium',107,'Transition Metal',7,7,'d',262.12,'Unavailable','Unavailable','Unavailable'],#Bh
171 ['Hassium',108,'Transition Metal',8,7,'d',265,'Unavailable','Unavailable','Unavailable'],#Hs
172 ['Meitnerium',109,'Unknown',9,7,'d',268,'Unavailable','Unavailable','Unavailable'],#Mt
173 ['Darmstadtium',110,'Unknown',10,7,'d',281,'Unavailable','Unavailable','Unavailable'],#Ds
174 ['Roentgenium',111,'Unknown',11,7,'d',280,'Unavailable','Unavailable','Unavailable'],#Rg
175 ['Copernicium',112,'Unknown',12,7,'d',277,'Unavailable','Unavailable','Unavailable'],#Cn
176 ['Nihonium',113,'Unknown',13,7,'p',287,'Unavailable','Unavailable','Unavailable'],#Nh
177 ['Flerovium',114,'Unknown',14,7,'p',289,'Unavailable','Unavailable','Unavailable'],#Fl
178 ['Moscovium',115,'Unknown',15,7,'p',288,'Unavailable','Unavailable','Unavailable'],#Mc
179 ['Livermorium',116,'Unknown',16,7,'p',293,'Unavailable','Unavailable','Unavailable'],#Lv
180 ['Tennessine',117,'Unknown',17,7,'p',292,'Unavailable','Unavailable','Unavailable'],#Ts
181 ['Oganesson',118,'Unknown',18,7,'p',294,'Solid',6.6,'Unavailable']]#Og
182
183
184if __name__ == '__main__': # Listing the information of elements
185
186 group_no_of_elements = [1] ; period_no_of_elements = [1] ; atomic_mass_of_elements = [1.01] ; block_of_elements = ['s'] ; name_of_elements = ['Hydrogen'] ; atomic_number_of_elements = [1] ; type_of_elements = ['Non Metal'] ; state_of_elements = ['Gaseous'] ; density_of_elements = [0.08] ; electronegativity_of_elements = [2.2]
187
188 group_no_of_elements_sec = [] ; period_no_of_elements_sec = [] ; atomic_mass_of_elements_sec = [] ; block_of_elements_sec = [] ; name_of_elements_sec = [] ; atomic_number_of_elements_sec = [] ; type_of_elements_sec = [] ; state_of_elements_sec = [] ; density_of_elements_sec = [] ; electronegativity_of_elements_sec = []
189
190
191 def add_to_list(a,b,c):
192
193 for i in range(a,b):
194 if c == ' ':
195 atomic_number_of_elements.append(" ")
196 name_of_elements.append(" ")
197 atomic_mass_of_elements.append(" ")
198 block_of_elements.append(" ")
199 group_no_of_elements.append(" ")
200 period_no_of_elements.append(" ")
201 type_of_elements.append(" ")
202 state_of_elements.append(" ")
203 density_of_elements.append(" ")
204 electronegativity_of_elements.append(" ")
205
206 elif c == 1:
207 name_of_elements.append(the_element_list[i][0])
208 atomic_number_of_elements.append(the_element_list[i][1])
209 type_of_elements.append(the_element_list[i][2])
210 group_no_of_elements.append(the_element_list[i][3])
211 period_no_of_elements.append(the_element_list[i][4])
212 block_of_elements.append(the_element_list[i][5])
213 atomic_mass_of_elements.append(the_element_list[i][6])
214 state_of_elements.append(the_element_list[i][7])
215 density_of_elements.append(the_element_list[i][8])
216 electronegativity_of_elements.append(the_element_list[i][9])
217
218 elif c == 2:
219 name_of_elements_sec.append(the_element_list[i][0])
220 atomic_number_of_elements_sec.append(the_element_list[i][1])
221 type_of_elements_sec.append(the_element_list[i][2])
222 group_no_of_elements_sec.append(the_element_list[i][3])
223 period_no_of_elements_sec.append(the_element_list[i][4])
224 block_of_elements_sec.append(the_element_list[i][5])
225 atomic_mass_of_elements_sec.append(the_element_list[i][6])
226 state_of_elements_sec.append(the_element_list[i][7])
227 density_of_elements_sec.append(the_element_list[i][8])
228 electronegativity_of_elements_sec.append(the_element_list[i][9])
229
230
231 add_to_list(0,16,' ')
232 add_to_list(1,4,1)
233 add_to_list(0,10,' ')
234 add_to_list(4,12,1)
235 add_to_list(0,10,' ')
236 add_to_list(12,56,1)
237 add_to_list(0,1,' ')
238 add_to_list(71,88,1)
239 add_to_list(0,1,' ')
240 add_to_list(103,118,1)
241 add_to_list(56,71,2)
242 add_to_list(88,103,2)
243
244
245if __name__ == '__main__': # Variables -- Toplevel Window's Names
246
247 tk_window = []
248 for i in range(0,126):
249 tk_window.append(i)
250
251 tk_window_2 = []
252 for i in range(0,30):
253 tk_window_2.append(i)
254
255
256if __name__ == '__main__': # Variables -- Symbols of elements in the Periodic Table
257
258 period_1 = ['H' ,'','','','','','','','','','','','','','','','','He']
259 period_2 = ['Li','Be','','','','','','','','','','','B','C','N','O','F','Ne']
260 period_3 = ['Na','Mg','','','','','','','','','','','Al','Si','P','S','Cl','Ar']
261 period_4 = """K Ca Sc Ti V Cr Mn Fe Co Ni Cu Zn Ga Ge As Se Br Kr""".split(" ")
262 period_5 = """Rb Sr Y Zr Nb Mo Tc Ru Rh Pd Ag Cd In Sn Sb Te I Xe""".split(" ")
263 period_6 = """Cs Ba * Hf Ta W Re Os Ir Pt Au Hg Tl Pb Bi Po At Rn""".split(" ")
264 period_7 = """Fr Ra ** Rf D Sg Bh Hs Mt Ds Rg Cn Nh Fl Mc Lv Ts Og""".split(" ")
265
266 period_6a = """La Ce Pr Nd Pm Sm Eu Gd Tb Dy Ho Er Tm Yb Lu""".split(" ")
267 period_7a = """Ac Th Pa U Np Pu Am Cm Bk Cf Es Fm Md No Lr""".split(" ")
268
269 # Making a list of main elements and secondary elements
270 main = period_1 + period_2 + period_3 + period_4 + period_5 + period_6 + period_7
271 sec = period_6a + period_7a
272
273
274if __name__ == '__main__': # Variables -- Colours for each group of simliar elements in the Periodic Table
275
276 # Colors for each group
277 non_m_col = '#feab90'
278 alk_m_col = '#ffe0b2'
279 alk_ea_col = '#fecc81'
280 trans_m_col = '#d2c4e8'
281 halogen_col = '#a4d7a7'
282 metals_col = '#feab90'
283 noble_g_col = '#fefffe'
284 act_col = '#b2e5fd'
285 rare_m_col = '#e7ee9a'
286 plain_but_col = 'grey'
287
288
289if __name__ == '__main__': # Using tkinter to display a Periodic Table of Elements
290
291 root = tk.Tk()
292 root.attributes('-fullscreen', True)
293 root.config(bg='purple')
294
295 tk.Label(root, text="Periodic Table of Elements", bg='purple', fg='white', font=['Bookman Old Style', 40, 'bold', 'underline']).place(relx=0.15, rely=0.02)
296
297
298 if __name__ == '__main__': # Frames for the Periodic Table
299
300 # Frame for the entire table
301 period_tab = tk.Frame(root, bg='grey', highlightbackground='black', highlightthickness=20)
302 period_tab.pack(side=tk.BOTTOM, pady=(0,50))
303
304 # Frame for the main elements only
305 main_elem = tk.Frame(period_tab)
306 main_elem.pack(padx=20, pady=20)
307
308 # Frame for the secondary elements only
309 sec_elem = tk.Frame(period_tab)
310 sec_elem.pack(pady=20, padx=20)
311
312
313 if __name__ == '__main__': # Function which creates a window of info for each element
314
315 def PT(window, name, symbol, atom_no, atom_mass, block, group, period, type, state, density, electronegativity):
316 if atom_no == ' ':
317 pass
318 else:
319 window = tk.Toplevel(root)
320 window.geometry('400x400')
321 window.config(bg='black')
322
323 tk.Label(window, text=name, bg='black', fg='white').place(relx=0.3, rely=0.1)
324
325 tk.Label(window, text=f"Symbol : {symbol}", bg='black', fg='white').place(relx=0.05, rely=0.3)
326 tk.Label(window, text=f"Atomic Number : {atom_no}", bg='black', fg='white').place(relx=0.05, rely=0.35)
327 tk.Label(window, text=f"Atomic Mass : {atom_mass}", bg='black', fg='white').place(relx=0.05, rely=0.4)
328 tk.Label(window, text=f"Block : {block}", bg='black', fg='white').place(relx=0.05, rely=0.45)
329 tk.Label(window, text=f"Group Number : {group}", bg='black', fg='white').place(relx=0.05, rely=0.5)
330 tk.Label(window, text=f"Period Number : {period}", bg='black', fg='white').place(relx=0.05, rely=0.55)
331 tk.Label(window, text=f"Type of element : {type}", bg='black', fg='white').place(relx=0.05, rely=0.6)
332 tk.Label(window, text=f"State of element : {state}", bg='black', fg='white').place(relx=0.05, rely=0.65)
333 tk.Label(window, text=f"Density : {density}", bg='black', fg='white').place(relx=0.05, rely=0.7)
334 tk.Label(window, text=f"Electronegativity : {electronegativity}", bg='black', fg='white').place(relx=0.05, rely=0.75)
335
336
337 if __name__ == '__main__': # Creating buttons for each element in the Periodic Table
338
339 # Creating a 7x18 table of buttons and appending it to a 2D python list for main elements
340 buttons = []
341 for i in range(7):
342 temp = []
343 for j in range(18):
344 but = tk.Button(main_elem,text=main[18*i+j],width=8,bg='#f0f0f0', command=partial(PT, tk_window[18*i+j], name_of_elements[18*i+j], main[18*i+j], atomic_number_of_elements[18*i+j], atomic_mass_of_elements[18*i+j], block_of_elements[18*i+j], group_no_of_elements[18*i+j], period_no_of_elements[18*i+j], type_of_elements[18*i+j], state_of_elements[18*i+j], density_of_elements[18*i+j], electronegativity_of_elements[18*i+j]))
345 but.grid(row=i,column=j)
346 temp.append(but)
347 buttons.append(temp)
348
349 # Creating a 2x15 table of buttons for secondary elements
350 for i in range(2):
351 for j in range(15):
352 if i == 0: # If row 1 then different color
353 tk.Button(sec_elem,text=sec[15*i+j],width=8,bg=rare_m_col, command=partial(PT, tk_window_2[15*i+j], name_of_elements_sec[15*i+j], sec[15*i+j], atomic_number_of_elements_sec[15*i+j], atomic_mass_of_elements_sec[15*i+j], block_of_elements_sec[15*i+j], group_no_of_elements_sec[15*i+j], period_no_of_elements_sec[15*i+j], type_of_elements_sec[15*i+j], state_of_elements_sec[15*i+j], density_of_elements_sec[15*i+j], electronegativity_of_elements_sec[15*i+j])).grid(row=i,column=j)
354 else:
355 tk.Button(sec_elem,text=sec[15*i+j],width=8,bg=act_col, command=partial(PT, tk_window_2[15*i+j], name_of_elements_sec[15*i+j], sec[15*i+j], atomic_number_of_elements_sec[15*i+j], atomic_mass_of_elements_sec[15*i+j], block_of_elements_sec[15*i+j], group_no_of_elements_sec[15*i+j], period_no_of_elements_sec[15*i+j], type_of_elements_sec[15*i+j], state_of_elements_sec[15*i+j], density_of_elements_sec[15*i+j], electronegativity_of_elements_sec[15*i+j])).grid(row=i,column=j)
356
357
358 if __name__ == '__main__': # Setting colours for each button
359
360 # Manually pick out main elements from the table
361 non_metals = buttons[0][0],buttons[1][12:16],buttons[2][13:16],buttons[3][14:16],buttons[4][15]
362 alk_metals = [row[0] for row in buttons[1:]]
363 alk_ea_metals = [row[1] for row in buttons[1:]]
364 halogens = [row[16] for row in buttons[1:]]
365 noble_gases = [row[-1] for row in buttons[:]]
366 transition_met = [buttons[x][3:12] for x in range(3,7)]
367 metals = buttons[6][12:16],buttons[5][12:16],buttons[4][12:15],buttons[3][12:14],buttons[2][12]
368 rare_metals = [row[2] for row in buttons[3:6]]
369 actinoid = buttons[-1][2]
370 plain_but = buttons[0][1:-1],buttons[1][2:12],buttons[2][2:12]
371
372 # Change colors for those main element buttons
373 actinoid['bg'] = act_col
374 for i in alk_metals:
375 i['bg'] = alk_m_col
376 for i in alk_ea_metals:
377 i['bg'] = alk_ea_col
378 for i in halogens:
379 i['bg'] = halogen_col
380 for i in noble_gases:
381 i['bg'] = noble_g_col
382 for i in rare_metals:
383 i['bg'] = rare_m_col
384
385 for i in transition_met:
386 for j in i:
387 j['bg'] = trans_m_col
388
389 for i in plain_but:
390 for j in i:
391 j['bg'] = plain_but_col
392
393 for i in non_metals:
394 if isinstance(i,list):
395 for j in i:
396 j.config(bg=non_m_col)
397 else:
398 i.config(bg=non_m_col)
399
400 for i in metals:
401 if isinstance(i,list):
402 for j in i:
403 j.config(bg=metals_col)
404 else:
405 i.config(bg=metals_col)
406
407 for i in plain_but:
408 for j in i:
409 j['relief'] = 'flat'
410
411
412 if __name__ == '__main__': # Creating a frame for categorizing elements on basis of their colours
413 legends_frame = tk.Canvas(root, bg='black', width=200, height=250)
414
415 tk.Label(legends_frame, text='Categories', bg='black', fg='white', font=['Bookman Old Style', 10, 'underline']).place(relx=0.25, rely=0.03)
416
417 labels = ['Actinides', 'Alkali Metals', 'Alkali Earth Metals', 'Halogens', 'Lanthanides', 'Metalloids', 'Noble Gases', 'Non Metals', 'Transition Metals']
418 colours = [act_col, alk_m_col, alk_ea_col, halogen_col, rare_m_col, metals_col, noble_g_col, non_m_col, trans_m_col]
419
420 for i in range(0,9):
421 tk.Label(legends_frame, text=labels[i], bg='black', fg=colours[i]).place(relx=0.4, rely=0.16+i*0.09)
422 tk.Canvas(legends_frame, bg=colours[i], width=32, height=12, borderwidth=0).place(relx=0.1, rely=0.16+i*0.09)
423
424 legends_frame.place(relx=0.8, rely=0.05)
425
426
427 tk.Button(root,text='EXIT',command=root.destroy).place(x=10, y=10)
428
429 root.mainloop()
430from tkinter import *
431
432period_1 = ['H' ,'','','','','','','','','','','','','','','','','He']
433period_2 = ['Li','Be','','','','','','','','','','','B','C','N','O','F','Ne']
434period_3 = ['Na','Mg','','','','','','','','','','','Al','Si','P','S','Cl','Ar']
435period_4 = """K Ca Sc Ti V Cr Mn Fe Co Ni Cu Zn Ga Ge As Se Br Kr""".split(" ")
436period_5 = """Rb Sr Y Zr Nb Mo Tc Ru Rh Pd Ag Cd In Sn Sb Te I Xe""".split(" ")
437period_6 = """Cs Ba * Hf Ta W Re Os Ir Pt Au Hg Tl Pb Bi Po At Rn""".split(" ")
438period_7 = """Fr Ra ** Rf D Sg Bh Hs Mt Ds Rg Cn Nh Fl Mc Lv Ts Og""".split(" ")
439
440period_6a = """La Ce Pr Nd Pm Sm Eu Gd Tb Dy Ho Er Tm Yb Lu""".split(" ")
441period_7a = """Ac Th Pa U Np Pu Am Cm Bk Cf Es Fm Md No Lr""".split(" ")
442
443# Making a list of main elements and secondary elements
444main = period_1 + period_2 + period_3 + period_4 + period_5 + period_6 + period_7
445sec = period_6a + period_7a
446
447# Colors for each group
448non_m_col = '#feab90'
449alk_m_col = '#ffe0b2'
450alk_ea_col = '#fecc81'
451trans_m_col = '#d2c4e8'
452halogen_col = '#a4d7a7'
453metals_col = '#feab90'
454noble_g_col = '#fefffe'
455act_col = '#b2e5fd'
456rare_m_col = '#e7ee9a'
457
458root = Tk()
459
460# Frame for the entire table
461period_tab = Frame(root)
462period_tab.pack()
463
464# Frame for the main elements only
465main_elem = Frame(period_tab)
466main_elem.pack()
467
468# Frame for the secondary elements only
469sec_elem = Frame(period_tab)
470sec_elem.pack(pady=10)
471
472# Creating a 7x18 table of buttons and appending it to a 2D python list for main elements
473buttons = []
474for i in range(7):
475 temp = []
476 for j in range(18):
477 but = Button(main_elem,text=main[18*i+j],width=10,bg='#f0f0f0')
478 but.grid(row=i,column=j)
479 temp.append(but)
480 buttons.append(temp)
481
482# Creating a 2x15 table of buttons for secondary elements
483for i in range(2):
484 for j in range(15):
485 text = sec[15*i+j]
486 if i == 0: # If row 1 then different color
487 Button(sec_elem,text=text,width=10,bg=rare_m_col).grid(row=i,column=j)
488 else:
489 Button(sec_elem,text=text,width=10,bg=act_col).grid(row=i,column=j)
490
491# Manually pick out main elements from the table
492non_metals = buttons[0][0],buttons[1][12:16],buttons[2][13:16],buttons[3][14:16],buttons[4][15]
493alk_metals = [row[0] for row in buttons[1:]]
494alk_ea_metals = [row[1] for row in buttons[1:]]
495halogens = [row[16] for row in buttons[1:]]
496noble_gases = [row[-1] for row in buttons[:]]
497transition_met = [buttons[x][3:12] for x in range(3,7)]
498metals = buttons[6][12:16],buttons[5][12:16],buttons[4][12:15],buttons[3][12:14],buttons[2][12]
499rare_metals = [row[2] for row in buttons[3:6]]
500actinoid = buttons[-1][2]
501plain_but = buttons[0][1:-1],buttons[1][2:12],buttons[2][2:12]
502
503# Change colors for those main element buttons
504actinoid['bg'] = act_col
505for i in alk_metals: i['bg'] = alk_m_col
506for i in alk_ea_metals: i['bg'] = alk_ea_col
507for i in halogens: i['bg'] = halogen_col
508for i in noble_gases: i['bg'] = noble_g_col
509for i in rare_metals: i['bg'] = rare_m_col
510
511for i in transition_met:
512 for j in i:
513 j['bg'] = trans_m_col
514
515for i in non_metals:
516 if isinstance(i,list):
517 for j in i:
518 j.config(bg=non_m_col)
519 else:
520 i.config(bg=non_m_col)
521
522for i in metals:
523 if isinstance(i,list):
524 for j in i:
525 j.config(bg=metals_col)
526 else:
527 i.config(bg=metals_col)
528
529for i in plain_but:
530 for j in i:
531 j['relief'] = 'flat'
532
533Button(root,text='EXIT',command=root.destroy).pack(pady=10)
534
535root.mainloop()
536
I've commented the code to make it more understandable. The slicing part might seem a bit complicated because python list does not support 2D slicing. One way is to create a numpy
array and store the coordinates onto it and then retrieve the respective button object based on coordinate, might be longer code but it would make the slicing more easier and understandable as numpy
supports 2D slicing.
Edit: Here is a more advanced and not so complicated periodic table
QUESTION
Unable to build and deploy Rails 6.0.4.1 app on heroku - Throws gyp verb cli error
Asked 2022-Jan-02 at 10:07Hi i was deploying a branch on heroku and threw up this error. I also tried deploying a branch which worked perfectly, but that is also showing the same error.
local yarn verion : 1.22.17 local node version : v12.22.7 Please help !!!
Tried building without yarn.lock and package-lock same thing.
This is how it starts Heroku deployment build log through CLI
1yarn install v1.22.17
2remote: warning package-lock.json found. Your project contains lock files generated by tools other than Yarn. It is advised not to mix package managers in order to avoid resolution inconsistencies caused by unsynchronized lock files. To clear this warning, remove package-lock.json.
3remote: [1/5] Validating package.json...
4remote: [2/5] Resolving packages...
5remote: [3/5] Fetching packages...
6remote: [4/5] Linking dependencies...
7remote: warning " > webpack-dev-server@4.6.0" has unmet peer dependency "webpack@^4.37.0 || ^5.0.0".
8remote: warning "webpack-dev-server > webpack-dev-middleware@5.2.1" has unmet peer dependency "webpack@^4.0.0 || ^5.0.0".
9remote: [5/5] Building fresh packages...
10remote: error /tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-sass: Command failed.
11remote: Exit code: 1
12remote: Command: node scripts/build.js
13remote: Arguments:
14remote: Directory: /tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-sass
15remote: Output:
16remote: Building: /tmp/build_df192222/bin/node /tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-gyp/bin/node-gyp.js rebuild --verbose --libsass_ext= --libsass_cflags= --libsass_ldflags= --libsass_library=
17remote: gyp info it worked if it ends with ok
18remote: gyp verb cli [
19remote: gyp verb cli '/tmp/build_df192222/bin/node',
20remote: gyp verb cli '/tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-gyp/bin/node-gyp.js',
21remote: gyp verb cli 'rebuild',
22
. . . . . `
1yarn install v1.22.17
2remote: warning package-lock.json found. Your project contains lock files generated by tools other than Yarn. It is advised not to mix package managers in order to avoid resolution inconsistencies caused by unsynchronized lock files. To clear this warning, remove package-lock.json.
3remote: [1/5] Validating package.json...
4remote: [2/5] Resolving packages...
5remote: [3/5] Fetching packages...
6remote: [4/5] Linking dependencies...
7remote: warning " > webpack-dev-server@4.6.0" has unmet peer dependency "webpack@^4.37.0 || ^5.0.0".
8remote: warning "webpack-dev-server > webpack-dev-middleware@5.2.1" has unmet peer dependency "webpack@^4.0.0 || ^5.0.0".
9remote: [5/5] Building fresh packages...
10remote: error /tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-sass: Command failed.
11remote: Exit code: 1
12remote: Command: node scripts/build.js
13remote: Arguments:
14remote: Directory: /tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-sass
15remote: Output:
16remote: Building: /tmp/build_df192222/bin/node /tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-gyp/bin/node-gyp.js rebuild --verbose --libsass_ext= --libsass_cflags= --libsass_ldflags= --libsass_library=
17remote: gyp info it worked if it ends with ok
18remote: gyp verb cli [
19remote: gyp verb cli '/tmp/build_df192222/bin/node',
20remote: gyp verb cli '/tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-gyp/bin/node-gyp.js',
21remote: gyp verb cli 'rebuild',
22remote: /app/.node-gyp/16.13.1/include/node/v8-internal.h: In function ‘void v8::internal::PerformCastCheck(T*)’:
23remote: /app/.node-gyp/16.13.1/include/node/v8-internal.h:492:38: error: ‘remove_cv_t’ is not a member of ‘std’; did you mean ‘remove_cv’?
24remote: 492 | !std::is_same<Data, std::remove_cv_t<T>>::value>::Perform(data);
25remote: | ^~~~~~~~~~~
26remote: | remove_cv
27remote: /app/.node-gyp/16.13.1/include/node/v8-internal.h:492:38: error: ‘remove_cv_t’ is not a member of ‘std’; did you mean ‘remove_cv’?
28remote: 492 | !std::is_same<Data, std::remove_cv_t<T>>::value>::Perform(data);
29remote: | ^~~~~~~~~~~
30remote: | remove_cv
31remote: /app/.node-gyp/16.13.1/include/node/v8-internal.h:492:50: error: template argument 2 is invalid
32remote: 492 | !std::is_same<Data, std::remove_cv_t<T>>::value>::Perform(data);
33remote: | ^
34remote: /app/.node-gyp/16.13.1/include/node/v8-internal.h:492:63: error: ‘::Perform’ has not been declared
35remote: 492 | !std::is_same<Data, std::remove_cv_t<T>>::value>::Perform(data);
36remote: | ^~~~~~~
37remote: ../src/binding.cpp: In function ‘Nan::NAN_METHOD_RETURN_TYPE render(Nan::NAN_METHOD_ARGS_TYPE)’:
38remote: ../src/binding.cpp:284:98: warning: cast between incompatible function types from ‘void (*)(uv_work_t*)’ {aka ‘void (*)(uv_work_s*)’} to ‘uv_after_work_cb’ {aka ‘void (*)(uv_work_s*, int)’} [-Wcast-function-type]
39remote: 284 | int status = uv_queue_work(uv_default_loop(), &ctx_w->request, compile_it, (uv_after_work_cb)MakeCallback);
40remote: | ^~~~~~~~~~~~
41remote: ../src/binding.cpp: In function ‘Nan::NAN_METHOD_RETURN_TYPE render_file(Nan::NAN_METHOD_ARGS_TYPE)’:
42remote: ../src/binding.cpp:320:98: warning: cast between incompatible function types from ‘void (*)(uv_work_t*)’ {aka ‘void (*)(uv_work_s*)’} to ‘uv_after_work_cb’ {aka ‘void (*)(uv_work_s*, int)’} [-Wcast-function-type]
43remote: 320 | int status = uv_queue_work(uv_default_loop(), &ctx_w->request, compile_it, (uv_after_work_cb)MakeCallback);
44remote: | ^~~~~~~~~~~~
45remote: In file included from ../../../../../nan/nan.h:58,
46remote: from ../src/binding.cpp:1:
47remote: ../src/binding.cpp: At global scope:
48remote: /app/.node-gyp/16.13.1/include/node/node.h:821:43: warning: cast between incompatible function types from ‘void (*)(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE)’ {aka ‘void (*)(v8::Local<v8::Object>)’} to ‘node::addon_register_func’ {aka ‘void (*)(v8::Local<v8::Object>, v8::Local<v8::Value>, void*)’} [-Wcast-function-type]
49remote: 821 | (node::addon_register_func) (regfunc), \
50remote: | ^
51remote: /app/.node-gyp/16.13.1/include/node/node.h:855:3: note: in expansion of macro ‘NODE_MODULE_X’
52remote: 855 | NODE_MODULE_X(modname, regfunc, NULL, 0) // NOLINT (readability/null_usage)
53remote: | ^~~~~~~~~~~~~
54remote: ../src/binding.cpp:358:1: note: in expansion of macro ‘NODE_MODULE’
55remote: 358 | NODE_MODULE(binding, RegisterModule);
56remote: | ^~~~~~~~~~~
57remote: make: *** [binding.target.mk:133: Release/obj.target/binding/src/binding.o] Error 1
58remote: make: Leaving directory '/tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-sass/build'
59remote: gyp ERR! build error
60remote: gyp ERR! stack Error: `make` failed with exit code: 2
61remote: gyp ERR! stack at ChildProcess.onExit (/tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-gyp/lib/build.js:262:23)
62remote: gyp ERR! stack at ChildProcess.emit (node:events:390:28)
63remote: gyp ERR! stack at Process.ChildProcess._handle.onexit (node:internal/child_process:290:12)
64remote: gyp ERR! System Linux 4.4.0-1097-aws
65remote: gyp ERR! command "/tmp/build_df192222/bin/node" "/tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-gyp/bin/node-gyp.js" "rebuild" "--verbose" "--libsass_ext=" "--libsass_cflags=" "--libsass_ldflags=" "--libsass_library="
66remote: gyp ERR! cwd /tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-sass
67remote: gyp ERR! node -v v16.13.1
68remote: gyp ERR! node-gyp -v v3.8.0
69remote: gyp ERR! not ok
70remote: Build failed with error code: 1
71remote:
72remote: !
73remote: ! Precompiling assets failed.
74remote: !
75remote: ! Push rejected, failed to compile Ruby app.
76remote:
77remote: ! Push failed
78
Though it is a Rails app I added node in engines to package.json.
1yarn install v1.22.17
2remote: warning package-lock.json found. Your project contains lock files generated by tools other than Yarn. It is advised not to mix package managers in order to avoid resolution inconsistencies caused by unsynchronized lock files. To clear this warning, remove package-lock.json.
3remote: [1/5] Validating package.json...
4remote: [2/5] Resolving packages...
5remote: [3/5] Fetching packages...
6remote: [4/5] Linking dependencies...
7remote: warning " > webpack-dev-server@4.6.0" has unmet peer dependency "webpack@^4.37.0 || ^5.0.0".
8remote: warning "webpack-dev-server > webpack-dev-middleware@5.2.1" has unmet peer dependency "webpack@^4.0.0 || ^5.0.0".
9remote: [5/5] Building fresh packages...
10remote: error /tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-sass: Command failed.
11remote: Exit code: 1
12remote: Command: node scripts/build.js
13remote: Arguments:
14remote: Directory: /tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-sass
15remote: Output:
16remote: Building: /tmp/build_df192222/bin/node /tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-gyp/bin/node-gyp.js rebuild --verbose --libsass_ext= --libsass_cflags= --libsass_ldflags= --libsass_library=
17remote: gyp info it worked if it ends with ok
18remote: gyp verb cli [
19remote: gyp verb cli '/tmp/build_df192222/bin/node',
20remote: gyp verb cli '/tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-gyp/bin/node-gyp.js',
21remote: gyp verb cli 'rebuild',
22remote: /app/.node-gyp/16.13.1/include/node/v8-internal.h: In function ‘void v8::internal::PerformCastCheck(T*)’:
23remote: /app/.node-gyp/16.13.1/include/node/v8-internal.h:492:38: error: ‘remove_cv_t’ is not a member of ‘std’; did you mean ‘remove_cv’?
24remote: 492 | !std::is_same<Data, std::remove_cv_t<T>>::value>::Perform(data);
25remote: | ^~~~~~~~~~~
26remote: | remove_cv
27remote: /app/.node-gyp/16.13.1/include/node/v8-internal.h:492:38: error: ‘remove_cv_t’ is not a member of ‘std’; did you mean ‘remove_cv’?
28remote: 492 | !std::is_same<Data, std::remove_cv_t<T>>::value>::Perform(data);
29remote: | ^~~~~~~~~~~
30remote: | remove_cv
31remote: /app/.node-gyp/16.13.1/include/node/v8-internal.h:492:50: error: template argument 2 is invalid
32remote: 492 | !std::is_same<Data, std::remove_cv_t<T>>::value>::Perform(data);
33remote: | ^
34remote: /app/.node-gyp/16.13.1/include/node/v8-internal.h:492:63: error: ‘::Perform’ has not been declared
35remote: 492 | !std::is_same<Data, std::remove_cv_t<T>>::value>::Perform(data);
36remote: | ^~~~~~~
37remote: ../src/binding.cpp: In function ‘Nan::NAN_METHOD_RETURN_TYPE render(Nan::NAN_METHOD_ARGS_TYPE)’:
38remote: ../src/binding.cpp:284:98: warning: cast between incompatible function types from ‘void (*)(uv_work_t*)’ {aka ‘void (*)(uv_work_s*)’} to ‘uv_after_work_cb’ {aka ‘void (*)(uv_work_s*, int)’} [-Wcast-function-type]
39remote: 284 | int status = uv_queue_work(uv_default_loop(), &ctx_w->request, compile_it, (uv_after_work_cb)MakeCallback);
40remote: | ^~~~~~~~~~~~
41remote: ../src/binding.cpp: In function ‘Nan::NAN_METHOD_RETURN_TYPE render_file(Nan::NAN_METHOD_ARGS_TYPE)’:
42remote: ../src/binding.cpp:320:98: warning: cast between incompatible function types from ‘void (*)(uv_work_t*)’ {aka ‘void (*)(uv_work_s*)’} to ‘uv_after_work_cb’ {aka ‘void (*)(uv_work_s*, int)’} [-Wcast-function-type]
43remote: 320 | int status = uv_queue_work(uv_default_loop(), &ctx_w->request, compile_it, (uv_after_work_cb)MakeCallback);
44remote: | ^~~~~~~~~~~~
45remote: In file included from ../../../../../nan/nan.h:58,
46remote: from ../src/binding.cpp:1:
47remote: ../src/binding.cpp: At global scope:
48remote: /app/.node-gyp/16.13.1/include/node/node.h:821:43: warning: cast between incompatible function types from ‘void (*)(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE)’ {aka ‘void (*)(v8::Local<v8::Object>)’} to ‘node::addon_register_func’ {aka ‘void (*)(v8::Local<v8::Object>, v8::Local<v8::Value>, void*)’} [-Wcast-function-type]
49remote: 821 | (node::addon_register_func) (regfunc), \
50remote: | ^
51remote: /app/.node-gyp/16.13.1/include/node/node.h:855:3: note: in expansion of macro ‘NODE_MODULE_X’
52remote: 855 | NODE_MODULE_X(modname, regfunc, NULL, 0) // NOLINT (readability/null_usage)
53remote: | ^~~~~~~~~~~~~
54remote: ../src/binding.cpp:358:1: note: in expansion of macro ‘NODE_MODULE’
55remote: 358 | NODE_MODULE(binding, RegisterModule);
56remote: | ^~~~~~~~~~~
57remote: make: *** [binding.target.mk:133: Release/obj.target/binding/src/binding.o] Error 1
58remote: make: Leaving directory '/tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-sass/build'
59remote: gyp ERR! build error
60remote: gyp ERR! stack Error: `make` failed with exit code: 2
61remote: gyp ERR! stack at ChildProcess.onExit (/tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-gyp/lib/build.js:262:23)
62remote: gyp ERR! stack at ChildProcess.emit (node:events:390:28)
63remote: gyp ERR! stack at Process.ChildProcess._handle.onexit (node:internal/child_process:290:12)
64remote: gyp ERR! System Linux 4.4.0-1097-aws
65remote: gyp ERR! command "/tmp/build_df192222/bin/node" "/tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-gyp/bin/node-gyp.js" "rebuild" "--verbose" "--libsass_ext=" "--libsass_cflags=" "--libsass_ldflags=" "--libsass_library="
66remote: gyp ERR! cwd /tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-sass
67remote: gyp ERR! node -v v16.13.1
68remote: gyp ERR! node-gyp -v v3.8.0
69remote: gyp ERR! not ok
70remote: Build failed with error code: 1
71remote:
72remote: !
73remote: ! Precompiling assets failed.
74remote: !
75remote: ! Push rejected, failed to compile Ruby app.
76remote:
77remote: ! Push failed
78{
79 "name": "travel_empire",
80 "private": true,
81 "dependencies": {
82 "@fortawesome/fontawesome-free": "^5.15.4",
83 "@popperjs/core": "^2.10.2",
84 "@rails/actioncable": "^6.0.0",
85 "@rails/activestorage": "^6.0.0",
86 "@rails/ujs": "^6.0.0",
87 "@rails/webpacker": "4.3.0",
88 "bootstrap": "4.3.1",
89 "bootstrap-icons": "^1.5.0",
90 "easy-autocomplete": "^1.3.5",
91 "jquery": "^3.6.0",
92 "jquery-ui-dist": "^1.12.1",
93 "js-autocomplete": "^1.0.4",
94 "node-sass": "^7.0.0",
95 "popper.js": "^1.16.1",
96 "turbolinks": "^5.2.0"
97 },
98 "version": "0.1.0",
99 "devDependencies": {
100 "webpack-dev-server": "^4.6.0"
101 },
102 "engines": {
103 "node": "16.x"
104 }
105}
106
Gemfile
1yarn install v1.22.17
2remote: warning package-lock.json found. Your project contains lock files generated by tools other than Yarn. It is advised not to mix package managers in order to avoid resolution inconsistencies caused by unsynchronized lock files. To clear this warning, remove package-lock.json.
3remote: [1/5] Validating package.json...
4remote: [2/5] Resolving packages...
5remote: [3/5] Fetching packages...
6remote: [4/5] Linking dependencies...
7remote: warning " > webpack-dev-server@4.6.0" has unmet peer dependency "webpack@^4.37.0 || ^5.0.0".
8remote: warning "webpack-dev-server > webpack-dev-middleware@5.2.1" has unmet peer dependency "webpack@^4.0.0 || ^5.0.0".
9remote: [5/5] Building fresh packages...
10remote: error /tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-sass: Command failed.
11remote: Exit code: 1
12remote: Command: node scripts/build.js
13remote: Arguments:
14remote: Directory: /tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-sass
15remote: Output:
16remote: Building: /tmp/build_df192222/bin/node /tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-gyp/bin/node-gyp.js rebuild --verbose --libsass_ext= --libsass_cflags= --libsass_ldflags= --libsass_library=
17remote: gyp info it worked if it ends with ok
18remote: gyp verb cli [
19remote: gyp verb cli '/tmp/build_df192222/bin/node',
20remote: gyp verb cli '/tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-gyp/bin/node-gyp.js',
21remote: gyp verb cli 'rebuild',
22remote: /app/.node-gyp/16.13.1/include/node/v8-internal.h: In function ‘void v8::internal::PerformCastCheck(T*)’:
23remote: /app/.node-gyp/16.13.1/include/node/v8-internal.h:492:38: error: ‘remove_cv_t’ is not a member of ‘std’; did you mean ‘remove_cv’?
24remote: 492 | !std::is_same<Data, std::remove_cv_t<T>>::value>::Perform(data);
25remote: | ^~~~~~~~~~~
26remote: | remove_cv
27remote: /app/.node-gyp/16.13.1/include/node/v8-internal.h:492:38: error: ‘remove_cv_t’ is not a member of ‘std’; did you mean ‘remove_cv’?
28remote: 492 | !std::is_same<Data, std::remove_cv_t<T>>::value>::Perform(data);
29remote: | ^~~~~~~~~~~
30remote: | remove_cv
31remote: /app/.node-gyp/16.13.1/include/node/v8-internal.h:492:50: error: template argument 2 is invalid
32remote: 492 | !std::is_same<Data, std::remove_cv_t<T>>::value>::Perform(data);
33remote: | ^
34remote: /app/.node-gyp/16.13.1/include/node/v8-internal.h:492:63: error: ‘::Perform’ has not been declared
35remote: 492 | !std::is_same<Data, std::remove_cv_t<T>>::value>::Perform(data);
36remote: | ^~~~~~~
37remote: ../src/binding.cpp: In function ‘Nan::NAN_METHOD_RETURN_TYPE render(Nan::NAN_METHOD_ARGS_TYPE)’:
38remote: ../src/binding.cpp:284:98: warning: cast between incompatible function types from ‘void (*)(uv_work_t*)’ {aka ‘void (*)(uv_work_s*)’} to ‘uv_after_work_cb’ {aka ‘void (*)(uv_work_s*, int)’} [-Wcast-function-type]
39remote: 284 | int status = uv_queue_work(uv_default_loop(), &ctx_w->request, compile_it, (uv_after_work_cb)MakeCallback);
40remote: | ^~~~~~~~~~~~
41remote: ../src/binding.cpp: In function ‘Nan::NAN_METHOD_RETURN_TYPE render_file(Nan::NAN_METHOD_ARGS_TYPE)’:
42remote: ../src/binding.cpp:320:98: warning: cast between incompatible function types from ‘void (*)(uv_work_t*)’ {aka ‘void (*)(uv_work_s*)’} to ‘uv_after_work_cb’ {aka ‘void (*)(uv_work_s*, int)’} [-Wcast-function-type]
43remote: 320 | int status = uv_queue_work(uv_default_loop(), &ctx_w->request, compile_it, (uv_after_work_cb)MakeCallback);
44remote: | ^~~~~~~~~~~~
45remote: In file included from ../../../../../nan/nan.h:58,
46remote: from ../src/binding.cpp:1:
47remote: ../src/binding.cpp: At global scope:
48remote: /app/.node-gyp/16.13.1/include/node/node.h:821:43: warning: cast between incompatible function types from ‘void (*)(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE)’ {aka ‘void (*)(v8::Local<v8::Object>)’} to ‘node::addon_register_func’ {aka ‘void (*)(v8::Local<v8::Object>, v8::Local<v8::Value>, void*)’} [-Wcast-function-type]
49remote: 821 | (node::addon_register_func) (regfunc), \
50remote: | ^
51remote: /app/.node-gyp/16.13.1/include/node/node.h:855:3: note: in expansion of macro ‘NODE_MODULE_X’
52remote: 855 | NODE_MODULE_X(modname, regfunc, NULL, 0) // NOLINT (readability/null_usage)
53remote: | ^~~~~~~~~~~~~
54remote: ../src/binding.cpp:358:1: note: in expansion of macro ‘NODE_MODULE’
55remote: 358 | NODE_MODULE(binding, RegisterModule);
56remote: | ^~~~~~~~~~~
57remote: make: *** [binding.target.mk:133: Release/obj.target/binding/src/binding.o] Error 1
58remote: make: Leaving directory '/tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-sass/build'
59remote: gyp ERR! build error
60remote: gyp ERR! stack Error: `make` failed with exit code: 2
61remote: gyp ERR! stack at ChildProcess.onExit (/tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-gyp/lib/build.js:262:23)
62remote: gyp ERR! stack at ChildProcess.emit (node:events:390:28)
63remote: gyp ERR! stack at Process.ChildProcess._handle.onexit (node:internal/child_process:290:12)
64remote: gyp ERR! System Linux 4.4.0-1097-aws
65remote: gyp ERR! command "/tmp/build_df192222/bin/node" "/tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-gyp/bin/node-gyp.js" "rebuild" "--verbose" "--libsass_ext=" "--libsass_cflags=" "--libsass_ldflags=" "--libsass_library="
66remote: gyp ERR! cwd /tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-sass
67remote: gyp ERR! node -v v16.13.1
68remote: gyp ERR! node-gyp -v v3.8.0
69remote: gyp ERR! not ok
70remote: Build failed with error code: 1
71remote:
72remote: !
73remote: ! Precompiling assets failed.
74remote: !
75remote: ! Push rejected, failed to compile Ruby app.
76remote:
77remote: ! Push failed
78{
79 "name": "travel_empire",
80 "private": true,
81 "dependencies": {
82 "@fortawesome/fontawesome-free": "^5.15.4",
83 "@popperjs/core": "^2.10.2",
84 "@rails/actioncable": "^6.0.0",
85 "@rails/activestorage": "^6.0.0",
86 "@rails/ujs": "^6.0.0",
87 "@rails/webpacker": "4.3.0",
88 "bootstrap": "4.3.1",
89 "bootstrap-icons": "^1.5.0",
90 "easy-autocomplete": "^1.3.5",
91 "jquery": "^3.6.0",
92 "jquery-ui-dist": "^1.12.1",
93 "js-autocomplete": "^1.0.4",
94 "node-sass": "^7.0.0",
95 "popper.js": "^1.16.1",
96 "turbolinks": "^5.2.0"
97 },
98 "version": "0.1.0",
99 "devDependencies": {
100 "webpack-dev-server": "^4.6.0"
101 },
102 "engines": {
103 "node": "16.x"
104 }
105}
106source 'https://rubygems.org'
107git_source(:github) { |repo| "https://github.com/#{repo}.git" }
108
109ruby '2.7.3'
110
111# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
112gem 'rails', '~> 6.0.3', '>= 6.0.3.7'
113
114gem 'mongoid', git: 'https://github.com/mongodb/mongoid.git'
115
116
117# Use Puma as the app server
118gem 'puma', '~> 4.1'
119# Use SCSS for stylesheets
120gem 'sass-rails', '>= 6'
121# Transpile app-like JavaScript. Read more: https://github.com/rails/webpacker
122gem 'webpacker', '~> 4.0'
123# Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks
124gem 'turbolinks', '~> 5'
125# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
126gem 'jbuilder', '~> 2.7'
127# Use Redis adapter to run Action Cable in production
128# gem 'redis', '~> 4.0'
129# Use Active Model has_secure_password
130
131
132# Use Active Storage variant
133# gem 'image_processing', '~> 1.2'
134
135
136gem 'axlsx'
137gem 'caxlsx_rails'
138
139
140#Bootstrap for UI
141gem 'bootstrap', '~> 5.1.0'
142gem 'bootstrap-timepicker-rails', '~> 0.1.3'
143gem 'bootstrap-select-rails', '~> 1.6', '>= 1.6.3'
144#JQuery Rails
145gem 'jquery-rails'
146
147 gem 'rails_12factor', group: :production
148# Reduces boot times through caching; required in config/boot.rb
149gem 'bootsnap', '>= 1.4.2', require: false
150
151group :development, :test do
152 # Call 'byebug' anywhere in the code to stop execution and get a debugger console
153 gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
154end
155
156group :development do
157 # Access an interactive console on exception pages or by calling 'console' anywhere in the code.
158 gem 'web-console', '>= 3.3.0'
159 gem 'listen', '~> 3.2'
160 gem 'pry'
161 # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
162 gem 'spring'
163 gem 'spring-watcher-listen', '~> 2.0.0'
164end
165
166group :test do
167 # Adds support for Capybara system testing and selenium driver
168 gem 'capybara', '>= 2.15'
169 gem 'selenium-webdriver'
170 # Easy installation and use of web drivers to run system tests with browsers
171 gem 'webdrivers'
172 gem 'cucumber-rails', require: false
173 gem 'database_cleaner'
174end
175
176# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
177gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
178
179#HTTParty for RESTful API calls
180gem 'httparty'
181
182
183#Paperclip for storing files
184gem 'paperclip'
185gem "mongoid-paperclip", :require => "mongoid_paperclip"
186
187gem "letter_opener", :group => :development
188
ANSWER
Answered 2021-Dec-18 at 14:32I had a similar problem but resolved by following steps.
- Run the following command.
heroku buildpacks:add heroku/nodejs --index 1
- Update node version from
16.x
to12.16.2
in package.json.
QUESTION
Log4j 1: How to mitigate the vulnerability in log4j without updating version to 2.15.0
Asked 2021-Dec-22 at 02:45I am using log4j 1.2.16. I am using this with maven selenium testng java project. I am looking for a solution without upgrading the version of log4j.
1<dependency>
2 <groupId>log4j</groupId>
3 <artifactId>log4j</artifactId>
4 <version>1.2.16</version>
5</dependency>
6
ANSWER
Answered 2021-Dec-16 at 15:08Since you're using log4j 1, the specific vulnerability is not present there. However, note the following from http://slf4j.org/log4shell.html:
Is log4j 1.x vulnerable? Given that log4j version 1.x is still very widely deployed, perhaps 10 times more widely than log4j 2.x, we have been receiving a steady stream of questions regarding the vulnerability of log4j version 1.x.
As log4j 1.x does NOT offer a JNDI look up mechanism at the message level, it does NOT suffer from CVE-2021-44228.
However, log4j 1.x comes with
JMSAppender
which will perform a JNDI lookup if enabled in log4j's configuration file, i.e. log4j.properties or log4j.xml.An attacker who ALREADY has write access the log4j configuration file will need to add
JMSAppender
into the configuration poisoned with malicious connection parameters. Note that prior legitimate usage ofJMSAppender
is irrelevant to the ability of the attacker to mount a successful attack.Also note that poisoning the configuration file is not enough. The attacker also needs to force log4j to reload its configuration file with the poisoned parameters. Given that log4j 1.x does not offer automatic reloading, the poisoned configuration file will typically only become effective at application restart.
Nevertheless, while not easy, such an attack is not impossible. Thus it makes some sense to make job of the attacker even harder by removing
JMSAppender
altogether from log4j-1.2.17.jar.In the absence of a new log4j 1.x release, you can remove
JMSAppender
from the log4j-1.2.17.jar artifact yourself. Here is the command:
1<dependency>
2 <groupId>log4j</groupId>
3 <artifactId>log4j</artifactId>
4 <version>1.2.16</version>
5</dependency>
6zip -d log4j-1.2.17.jar org/apache/log4j/net/JMSAppender.class
7
If you do not have access to 'zip', you can also use the 'jar' command.
1<dependency>
2 <groupId>log4j</groupId>
3 <artifactId>log4j</artifactId>
4 <version>1.2.16</version>
5</dependency>
6zip -d log4j-1.2.17.jar org/apache/log4j/net/JMSAppender.class
7#assuming log4j-1.2.17.jar exists in current directory
8mkdir tmp
9cd tmp
10jar xvf ../log4j-1.2.17.jar
11rm org/apache/log4j/net/JMSAppender.class
12jar cvf ../log4j-1.2.17-patched.jar .
13
It goes without saying that once log4j-1.2.17.jar is patched, you would need to deploy it.
QUESTION
TypeError: WebDriver.__init__() got an unexpected keyword argument 'firefox_options' error using firefox_options as arguments in Selenium Python
Asked 2021-Dec-12 at 22:00I'm trying to create a script which downloads a file from a website and for this I want to change the download filepath. When I try to do this with the Firefox options it gives me this error:
1TypeError: WebDriver.__init__() got an unexpected keyword argument 'firefox_options'
2
Code:
1TypeError: WebDriver.__init__() got an unexpected keyword argument 'firefox_options'
2from selenium import webdriver
3from selenium import webdriver
4from selenium.webdriver.common.by import By
5from selenium.webdriver.firefox.options import Options
6from selenium.webdriver.common.keys import Keys
7import time
8
9options = Options()
10
11options.add_argument("download.default_directory=C:\\Music")
12browser = webdriver.Firefox(firefox_options=options, executable_path=r'C:\\selenium\\geckodriver.exe')
13browser.get('https://duckduckgo.com/')
14
ANSWER
Answered 2021-Dec-12 at 21:50The browser option parameter firefox_options
was deprecated in Selenium 3.8.0
- Browser option parameters are now standardized across drivers as
options
.firefox_options
,chrome_options
, andie_options
are now deprecated
Instead you have to use options
as follows:
1TypeError: WebDriver.__init__() got an unexpected keyword argument 'firefox_options'
2from selenium import webdriver
3from selenium import webdriver
4from selenium.webdriver.common.by import By
5from selenium.webdriver.firefox.options import Options
6from selenium.webdriver.common.keys import Keys
7import time
8
9options = Options()
10
11options.add_argument("download.default_directory=C:\\Music")
12browser = webdriver.Firefox(firefox_options=options, executable_path=r'C:\\selenium\\geckodriver.exe')
13browser.get('https://duckduckgo.com/')
14from selenium.webdriver.firefox.options import Options
15
16options = Options()
17options.add_argument("download.default_directory=C:\\Music")
18browser = webdriver.Firefox(options=options, executable_path=r'C:\\selenium\\geckodriver.exe')
19
Community Discussions contain sources that include Stack Exchange Network
Tutorials and Learning Resources in Selenium
Tutorials and Learning Resources are not available at this moment for Selenium